1st.深入理解v-model
我们都知道 v-model指令是vue用来双向绑定数据的,但其实v-mode也是vue封装起来的指令。v-model指令其实就是对v-bind:value 和 v-on:input的简写,所以在自定义组件中,只要有v-bind:value绑定value属性和v-on:input绑定input事件,就可以使用v-model指令来双向绑定:
<b-counter :label="yf.label" :value="yf.count" @input="yf.count = $event"></b-counter>
<b-counter :label="kz.label" v-model="kz.count"></b-counter>
上面两行代码的效果是一样的,都可以双向绑定自定义组件的数据,使得在自定义组件内部修改的值能在页面中更新。可以看到,第一行代码使用的变量名是value,自定义事件名是input,此时,可以使用v-model来绑定value的数据,这样就达到双向绑定的目的了。
2nd. .sync修饰符
大多数情况下,自定义组件都会有多个自定义属性,因为自定义属性不能重名,value只能有一个,所以v-model在这里就不适用了。转而用.sync修饰符。
使用.sync修饰符可以简化调用的过程, 它需要触发的事件名称是 update:属性名 格式才可以使用:
//自定义组件中定义自定义事件
watch: {
yfCount(nval) {
this.$emit("update:yf", nval)
},
kzCount(nval) {
this.$emit("update:kz", nval)
},
xzCount(nval) {
this.$emit("update:xz", nval)
},
}
定义好 update:属性名 格式的自定义属性后,在使用这个属性时只需要在后面.sync便可以实现双向绑定
<b-counter :yf.sync="yf" :kz.sync="kz" :xz.sync="xz"></b-counter>
3rd. 具名插槽
前几节说过,slot就是插槽,它可以把自定义组件的两个标签中间的内容在自定义组件中的slot标签中显示。但是这种方法只能把内容一股脑的全部塞入slot,不能灵活的控制需要显示的位置。为了解决这个问题,就需要使用具名插槽。
具名插槽需要给slot一个name属性,把这个slot放在需要的地方,想要控制模块往这个具名插槽添加时,需要给模块一个template容器,并且给属性v-slot(v-slot: 缩写是 # ),属性值就是需要放入的插槽的name属性值。设置好了之后,被template容器包裹的模块就会在对应name值的slot标签中渲染:
//自定义组件插槽
<slot name="header"></slot>
//使用自定义组件时使用template容器包裹
<b-box>
<!-- template标签指定它里面的内容在哪一个具体的插槽中呈现 -->
<template v-slot:header>
<h4>好好学习</h4>
</template>
</b-box>
4rd. 作用域插槽
作用域插槽就是在slot标签上绑定属性,这样外面在使用该插槽时,就可以获取并且操作上面绑定的数据。
//作用域插槽
//使用绑定属性的方法给页面传值
<slot name="del" :list = "list" :index="index"></slot>
//自定义组件内部数据
list:[
{
id:1001,
name:"苹果",
price:5999
},
{
id:1004,
name:"三星",
price:4999
}
]
注意,使用作用域插槽需要在具名插槽的基础上,给slot一个name属性
然后,在使用作用域插槽时使用 v-slot:del="接受参数" (v-slot: 缩写是 # )来接收作用域插槽传过来的值,一般 scope 接收,然后就可以在这个template 中使用这个数据了。
<b-box>
<template #del="scope" >
<button @click="del(scope)">删除</button>
</template>
</b-box>
5rd. 混入
混入是为了解决vue中代码复用的问题,在混入中写的代码将在之后的所有的vue实例中执行。
使用mixin()方法,该方法的参数是配置对象,Vue实例可以配置的东西,它都可以配置。 比如:数据,方法,生命周期钩子函数,计算属性,侦听器,过滤器,等等
在全局混入的内容,之后创建的所有Vue实例包括组件实例都将拥有。在创建Vue实例时,会将mixin里面的成员跟Vue实例自身的成员进行合并,如果冲突了,最终采用Vue实例身上的成员。
特别注意:生命周期钩子不是合并,是叠加执行,是先执行mixin里面的生命周期钩子,再执行Vue实例里面的生命周期钩子。
//配置混入对象
Vue.mixin({
data() {
return {
name:"张三",
age:18
}
},
mounted() {
console.log("mixin 挂载完成");
},
methods: {
log(){
console.log("mixin打印");
}
},
})
//之后创建的vue实例都会包含混入的内容
new Vue({
el:'#app',
data:{
},
methods: {
log(){
console.log("app 打印");
}
},
mounted() {
console.log("app 挂载完成");
},
})