一、使用场景
有两个甚至多个相似的组件,他们有相似的地方,也有不同的地方,这个时候你可能会通过pops传参加以区分,但是这种逻辑一多,代码就会变得难以理解甚至难以维护,这个时候,就可以使用mixin了。
混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
二、如何使用
第一步:新建一个mixins.js文件
export const mymixin={
//任意可公共使用的代码
}
第二步:引入
<script>
import { mymixin } from '../../mixins/TestFunMixin'
export default {
mixins: [mymixin],
}
</script>
三、合并规则
1.数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。
var mixin = {
data: function () {
return {
message: 'hello',
foo: 'abc'
}
}
}
new Vue({
mixins: [mixin],
data: function () {
return {
message: 'goodbye',
bar: 'def'
}
},
created: function () {
console.log(this.$data)
// => { message: "goodbye", foo: "abc", bar: "def" }
}
})
2.同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。
var mixin = {
created: function () {
console.log('混入对象的钩子被调用')
}
}
new Vue({
mixins: [mixin],
created: function () {
console.log('组件钩子被调用')
}
})
// => "混入对象的钩子被调用"
// => "组件钩子被调用"
3.值为对象的选项,例如 methods、components 和 directives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。
var mixin = {
methods: {
foo: function () {
console.log('foo')
},
conflicting: function () {
console.log('from mixin')
}
}
}
var vm = new Vue({
mixins: [mixin],
methods: {
bar: function () {
console.log('bar')
},
conflicting: function () {
console.log('from self')
}
}
})
vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"
四、全局混入
混入也可以进行全局注册。使用时格外小心!一旦使用全局混入,它将影响每一个之后创建的 Vue 实例。使用恰当时,这可以用来为自定义选项注入处理逻辑。(请谨慎使用全局混入,因为它会影响每个单独创建的 Vue 实例 (包括第三方组件)。大多数情况下,只应当应用于自定义选项,就像上面示例一样。推荐将其作为插件发布,以避免重复应用混入。)
// 为自定义的选项 'myOption' 注入一个处理器。
Vue.mixin({
created: function () {
var myOption = this.$options.myOption
if (myOption) {
console.log(myOption)
}
}
})
new Vue({
myOption: 'hello!'
})
// => "hello!"
五、自定义选项合并策略
自定义选项将使用默认策略,即简单地覆盖已有值。如果想让自定义选项以自定义逻辑合并,可以使用 Vue.config.optionMergeStrategies(optionMergeStrategies 主要用于 mixin 以及 Vue.extend() 方法时对于子组件和父组件如果有相同的属性(option)时的合并策略)
默认合并策略defaultStrat如下:
var defaultStrat = function (parentVal, childVal) {
return childVal === undefined
? parentVal
: childVal
}
可以看到,两个参数 parentVal, childVal 分别对应于父组件和子组件的选项,合并的策略就是,子组件的选项不存在,才会使用父组件的选项,如果子组件的选项存在,使用子组件自身的。
向Vue.config.optionMergeStrategies添加函数
Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) {
// 返回合并后的值
}
六、与Vuex的区别
Vuex是状态共享管理,所以Vuex中的变量和方法一旦发生改变所有引用该变量或方法的地方都会改变,而mixins中的实例不共享且互不影响,相当于每个应用mixin的实例都独立开辟了一片内存空间用于存储该mixin。
七、与父子组件之间的区别
子组件在引用之后相当于在父组件内开辟了一块单独的空间,来根据父组件props过来的值进行相应的操作,但本质上两者还是泾渭分明,相对独立。
而mixins则是在引入组件之后,将组件内部的内容如data等方法、method等属性与父组件相应内容进行合并。相当于在引入后,父组件的各种属性方法都被扩充了。
mixin作用:多个组件可以共享数据和方法,在使用mixin的组件中引入后,mixin中的方法和属性也就并入到该组件中,可以直接使用。钩子函数会两个都被调用,mixin中的钩子首先执行。