系列文章目录
第一章:Vue基础知识笔记(模板语法、数据绑定、事件处理、计算属性)(一)
第二章:Vue基础知识(计算属性、监视属性、computed和watch之间的区别、绑定样式)(二)
第三章:Vue基础知识(条件渲染、列表渲染、收集表单数据、过滤器)(三)
第四章:Vue基础知识(内置指令、自定义指令、Vue生命周期)(四)
第五章:Vue基础知识之组件机制(非单文件组件、单文件组件)(五)
第六章:Vue创建脚手架(六)
第八章:Vue组件通信(组件的自定义事件、全局事件总线、消息订阅与发布、插槽、props)(八)
文章目录
- 系列文章目录
- 一、ref属性
- 二、props配置项(父子组件间通信)
- 三、mixin(混入)
- 四、插件
- 五、scoped样式
一、ref属性
- 被用来给元素或子组件注册引用信息(
id的替代者
) - 应用在
html标签
上获取的是真实DOM元素
,应用在组件标签
上是组件实例对象
(vc) - 使用方式:
- 打标识:
.....
或
- 获取:
this.$refs.xxx
- 打标识:
案例(代码片段):
<template><div><h1 v-text="msg" ref="title"></h1><button ref="btn" @click="showDOM">点我输出上方的DOM元素</button><School ref="sch"/></div></template><script>//引入School组件import School from './components/School'export default {name:'App',components:{School},data() {return {msg:'欢迎学习Vue!'}},methods: {showDOM(){console.log(this.$refs.title) //真实DOM元素console.log(this.$refs.btn) //真实DOM元素console.log(this.$refs.sch) //School组件的实例对象(vc)}},}</script>
运行结果:
二、props配置项(父子组件间通信)
功能: 让组件接收外部传过来的数据(可用于父子间通信)
传递数据:
接收数据:
- 第一种方式(只接收):
props:['name']
- 第二种方式(限制类型):
props:{name:String}
- 第三种方式(限制类型、限制必要性、指定默认值):
- 第一种方式(只接收):
props:{ name:{ type:String, //类型 required:true, //必要性 default:'老王' //默认值 } }
备注: props是只读的
,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改
,那么请复制props的内容到data中一份
,然后去修改data中的数据
。
父组件给子组件传递数据案例(代码片段):
App.vue
<template><div>//数值类型需要使用v-bind进行传递,否则传递过去的会为String类型<Student name="李四" sex="女" :age="18"/></div></template><script>import Student from './components/Student'export default {name:'App',components:{Student}}</script>
Student.vue
<template> <div> <h1>{{ msg }}</h1> <h2>学生姓名:{{ name }}</h2> <h2>学生性别:{{ sex }}</h2> <h2>学生年龄:{{ myAge + 1 }}</h2> <button @click="updateAge">尝试修改收到的年龄</button> </div></template><script>export default { name: "Student", data() { console.log(this); return { msg: "我是一个尚硅谷的学生", myAge: this.age, }; }, methods: { updateAge() { this.myAge++; }, }, //简单声明接收 // props:['name','age','sex'] //接收的同时对数据进行类型限制 /* props:{name:String,age:Number,sex:String} */ //接收的同时对数据:进行类型限制+默认值的指定+必要性的限制 props: { name: { type: String, //name的类型是字符串 required: true, //name是必要的 }, age: { type: Number, default: 99, //默认值 }, sex: { type: String, required: true, }, },};</script>
运行结果:
上述案例实现了,父组件给子组件传递数据,那么是否可以利用props实现子组件给父组件传递数据呢?
那么就让父组件给子组件传递一个函数
,让子组件在内部调用父组件传递过来的函数,通过给函数传递实参,将子组件的数据传递给父组件。
子组件给父组件传递数据案例(代码片段):
App.vue
<template><div class="app"><!-- 通过父组件给子组件传递函数类型的props实现:子给父传递数据 --><School :getSchoolName="getSchoolName"/></div></template><script>import Student from './components/Student'export default {name:'App',components:{Student},data() {return {msg:'你好啊!',studentName:''}},methods: {getSchoolName(name){console.log('App收到了学校名:',name)},},}</script>
School.vue
<template> <div class="school"> <h2>学校名称:{{ name }}</h2> <h2>学校地址:{{ address }}</h2> <button @click="sendSchoolName">把学校名给App</button> </div></template><script>export default { name: "School", props: ["getSchoolName"], data() { return { name: "你猜", address: "你猜", }; }, methods: { sendSchoolName() { this.getSchoolName(this.name); }, },};</script>
运行结果:
三、mixin(混入)
在开发中,我们会定义多个组件,而组件中避免不了出现属性和方法重复的情况,造成代码冗余;我们可以
把重复的属性和方法定义在mixin中
,组件可以引入mixin
,把这个mixin中的属性和方法当做基础结构。
功能: 可以把
多个组件共用的配置提取成一个混入对象
使用方式:
第一步定义混入(共同属性和方法):export const hunhe{ data(){....}, methods:{....} ....}
第二步使用混入:
全局混入:Vue.mixin(xxx)
局部混入:mixins:['xxx']
main.js中全局使用
import {mixin1,mixin2} from './mixin'Vue.mixin(mixin1)Vue.mixin(mixin2)
其他组件中使用:
<script>//引入import {mixin1,mixin2} from './mixin'export default { data() {...}, mixins: [mixin1, mixin2],};</script>
注意:
1.数据对象
在内部会进行递归合并,并在发生冲突
时以组件数据优先
。
2.同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用
。
3.值为对象的选项,例如 methods、components 和 directives,将被合并为同一个对象。两个对象键名冲 突时,取组件对象的键值对
。
案例(代码片段):
App.vue
<template><div><School/><hr><Student/></div></template><script>import School from './components/School'import Student from './components/Student'export default {name:'App',components:{School,Student}}</script>
mixin.js
export const mixin1 = { methods: { showName() { alert(this.name) } }, mounted() { console.log('你好啊!') },}export const mixin2 = { data() { return { x: 100, y: 200 } },}
Student.vue
<template> <div> <h2 @click="showName">学生姓名:{{ name }}</h2> <h2>学生性别:{{ sex }}</h2> {{ x }}{{ y }} </div></template><script>import { mixin1, mixin2 } from "../mixin";export default { name: "Student", data() { return { name: "张三", sex: "男", }; }, mixins: [mixin1, mixin2],};</script>
School.vue
<template> <div> <h2 @click="showName">学校名称:{{ name }}</h2> <h2>学校地址:{{ address }}</h2> {{ x }}{{ y }} </div></template><script>//引入import { mixin1, mixin2 } from "../mixin";export default { name: "School", data() { return { name: "你猜", address: "你猜", x: 666, }; }, mixins: [mixin1, mixin2],};</script>
运行结果:
使用共同的点击事件
四、插件
插件通常用来为 Vue 添加全局功能。
功能: 用于增强Vue
本质: 包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。
定义插件:
对象.install = function (Vue, options) { // 1. 添加全局过滤器 Vue.filter(....) // 2. 添加全局指令 Vue.directive(....) // 3. 配置全局混入(合) Vue.mixin(....) // 4. 添加实例方法 Vue.prototype.$myMethod = function () {...} Vue.prototype.$myProperty = xxxx}
使用插件:
Vue.use()
案例(代码片段):
plugins.js
export default {install(Vue,x,y,z){console.log(x,y,z)//全局过滤器Vue.filter('mySlice',function(value){return value.slice(0,4)})//定义全局指令Vue.directive('fbind',{//指令与元素成功绑定时(一上来)bind(element,binding){element.value = binding.value},//指令所在元素被插入页面时inserted(element,binding){element.focus()},//指令所在的模板被重新解析时update(element,binding){element.value = binding.value}})//定义混入Vue.mixin({data() {return {x:100,y:200}},})//给Vue原型上添加一个方法(vm和vc就都能用了)Vue.prototype.hello = ()=>{alert('你好啊')}}}
main.js 中引入代码
//引入插件import plugins from './plugins'//应用(使用)插件Vue.use(plugins,1,2,3)
School.vue 组件使用插件
<template> <div> <h2>学校名称:{{ name | mySlice }}</h2> <h2>学校地址:{{ address }}</h2> <button @click="test">点我测试一个hello方法</button> <input type="text" v-fbind:value="name" /> </div></template><script>export default { name: "School", data() { return { name: "你猜", address: "你猜", }; }, methods: { test() { this.hello(); }, },};</script>
运行结果:
引入的全局方法生效
五、scoped样式
- 作用:让样式在局部生效,防止冲突。
- 写法: