Vue 之 混入(mixins)
混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
个人理解
混入(mixins)类似继承关系,即 extends,只不过在vue中使用Mixins代替了。当多个页面执行的方法和需要的数据类似时,我们可以选择使用 mixins 对相同数据进行封装,然后混入到对应组件中使用。
与Vuex的区别
vuex 中的方法和变量是可以相互读取并相互更改的。
mixins 可以定义公用的变量或方法,但是mixin中的数据是不共享的,也就是每个组件中的mixin实例都是不一样的,都是单独存在的个体,不存在相互影响的;
以提示框,确认框为例。从继承的角度来理解混入。
1. 可以使用父类的属性或方法:
// 定义混入对象
const toggle = {
data () {
isShow: false,
title: '提示',
content: '提示内容'
},
methods: {
toggleShow() {
this.isShow= !this.isShow
}
}
}
// 使用混入
const Alert = {
template: '#alert',
mixins: [toggle]
};
const Confirm = {
template: '#confirm',
mixins: [toggle]
};
组件的“父类”中定义一个data、methods、computed等,只要组件中混入了这个父类,那么就可以在组件中使用父类相应的方法或属性。
Alert 和 Confirm 组件都使用父类 toggle中的 isShow 作为显示/隐藏控制,toggleShow() 方法控制切换显示状态。
2. 覆盖父类的同名属性或方法:
// 定义混入对象
const toggle = {
data () {
isShow: false,
title: '标题',
content: '提示文字'
},
methods: {
toggleShow() {
this.isShow= !this.isShow
}
}
}
// 使用混入
const Alert = {
template: '#alert',
mixins: [toggle],
data() {
title: '提示'
}
};
const Confirm = {
template: '#confirm',
mixins: [toggle],
data() {
title: '警告',
content: '是否确认删除?'
},
methods: {
toggleShow() {
this.isShow= !this.isShow;
console.log('输入日志');
}
}
};
组件中定义一个属性/方法,然而它混入的“父类”中已经定义了这个属性/方法,那么子类将会覆盖“父类”的这个属性/方法。
Alert 组件使用时, title 默认为 ‘提示’,而不是 ‘标题’。content默认为父类中的 ‘提示文字’。
Confirm 组件使用时,title 默认为 ‘警告’,content 默认为 ‘是否确认删除?’。在调用 toggleShow 方法时也会在控制台打印日志信息。
3. 构造函数都会触发
// 定义混入对象
const toggle = {
created: () => {
console.log('混入对象的钩子被调用')
}
}
// 使用混入
const Alert = {
template: '#alert',
mixins: [toggle],
created: () => {
console.log('组件钩子被调用')
}
};
组件中的钩子函数就像类中的构造函数,当调用子类时,子类的构造函数和父类的构造函数就都会触发,并且父类的构造函数将会在子类的构造函数之前触发。
Alert 组件在使用时, 先打印 ‘混入对象的钩子被调用’,后打印 ‘组件钩子被调用’。
全局混入
当所有的组件中都需要某个方法或数值时,可使用全局混入。此后创建的所以Vue实例均会搜到影响。
Vue.mixin({
methods: {
mixinOne: function() {
console.log('mixinOne')
}
}
})
new Vue({
el: '#app',
methods: {
mixinTwo: function () {
console.log('mixinTwo')
}
},
mounted() {
this.mixinOne()
this.mixinTwo()
}
})
总结
-
混入对于封装一小段想要复用的代码来讲是有用的。而全局混入时将被注册到了每个组件上。因此,它们的使用场景极其有限并且要非常的小心。
-
混入可以定义公用的变量或方法,但数据是不共享的。各组件之间无影响。
-
当组件和混入对象含有同名选项时,这些选项将以恰当的方式混合。
对象 合并方式 钩子函数 同名钩子函数将会混合为一个数组,都将被调用到,但混入对象的钩子将在组件自身钩子之前调用。 值为对象的选项 将被混合为同一个对象。两个对象键名冲突时,取组件对象的键值对。 注: 钩子函数包括 created、mounted 等,而 components、methods 、computed、data 等为值对象。(watch会将每个watcher合并成一个数组,按照数组从头顺序调用触发)
可使用 Vue.config.optionMergeStrategies 自定义合并策略。详情见 https://www.jianshu.com/p/4ab8d255d070