我之前一直以为mixin的合并是以组件内的优先,即mixin的内容如果和组件内有冲突的,以组件内为准,确实存在这种情况,但是vue指定的策略更详细,下面分别记录各种情况对应的合并策略基本基本当一个组件使用mixin的时候,所有mixin的选项会被混入到组件自己的选项中, 这部分没什么好说的,直接看代码
// define a mixin object
const myMixin = {
created() {

this.hello()
},
methods: {

hello() {

console.log('hello from mixin!')

}
}
}

// define an app that uses this mixin
const app = Vue.createApp({
mixins: [myMixin]
})

app.mount('#mixins-basic') // => "hello from mixin!"

// define a mixin object
const myMixin = {
created() {

this.hello()
},
methods: {

hello() {

console.log('hello from mixin!')

}
}
}

// define an app that uses this mixin
const app = Vue.createApp({
mixins: [myMixin]
})

app.mount('#mixins-basic') // => "hello from mixin!"
选项的合并策略选项的合并策略这里的选项指的就是 data methods和生命周期钩子函数这些选项,他们的会采取不同的合并策略像data,methods,components,directives这样的会被合并进同一个对象中,并且遇到冲突项以组件的为准
const myMixin = {
data() {

return {

message: 'hello',

foo: 'abc'

}
}
}

const app = Vue.createApp({
mixins: [myMixin],
data() {

return {

message: 'goodbye',

bar: 'def'

}
},
created() {

console.log(this.$data) // => { message: "goodbye", foo: "abc", bar: "def" }
}
})

const myMixin = {
data() {

return {

message: 'hello',

foo: 'abc'

}
}
}

const app = Vue.createApp({
mixins: [myMixin],
data() {

return {

message: 'goodbye',

bar: 'def'

}
},
created() {

console.log(this.$data) // => { message: "goodbye", foo: "abc", bar: "def" }
}
})

const myMixin = {
methods: {

foo() {

console.log('foo')

},

conflicting() {

console.log('from mixin')

}
}
}

const app = Vue.createApp({
mixins: [myMixin],
methods: {

bar() {

console.log('bar')

},

conflicting() {

console.log('from self')

}
}
})

const vm = app.mount('#mixins-basic')

vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"

const myMixin = {
methods: {

foo() {

console.log('foo')

},

conflicting() {

console.log('from mixin')

}
}
}

const app = Vue.createApp({
mixins: [myMixin],
methods: {

bar() {

console.log('bar')

},

conflicting() {

console.log('from self')

}
}
})

const vm = app.mount('#mixins-basic')

vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"
而对于钩子函数就不是简单的替换了,如果有同名的,他们会被一起合并进数组中,然后依次调用,且mixin的钩子函数会率先被调用
const myMixin = {
created() {

console.log('mixin hook called')
}
}

const app = Vue.createApp({
mixins: [myMixin],
created() {

console.log('component hook called')
}
})

// => "mixin hook called"
// => "component hook called"

const myMixin = {
created() {

console.log('mixin hook called')
}
}

const app = Vue.createApp({
mixins: [myMixin],
created() {

console.log('component hook called')
}
})

// => "mixin hook called"
// => "component hook called"
全局混入和自定义选项全局混入和自定义选项
const app = Vue.createApp({
myOption: 'hello!'
})

// inject a handler for `myOption` custom option
app.mixin({
created() {

const myOption = this.$options.myOption

if (myOption) {

console.log(myOption)

}
}
})

app.mount('#mixins-global') // => "hello!"

const app = Vue.createApp({
myOption: 'hello!'
})

// inject a handler for `myOption` custom option
app.mixin({
created() {

const myOption = this.$options.myOption

if (myOption) {

console.log(myOption)

}
}
})

app.mount('#mixins-global') // => "hello!"
上述代码,我们在全局创建了一个自定义选项,然后进行了全局混入处理,但是需要注意的是,这会影响到这个app所有的子组件:
const app = Vue.createApp({
myOption: 'hello!'
})

// inject a handler for `myOption` custom option
app.mixin({
created() {

const myOption = this.$options.myOption

if (myOption) {

console.log(myOption)

}
}
})

// add myOption also to child component
app.component('test-component', {
myOption: 'hello from component!'
})

app.mount('#mixins-global')

// => "hello!"
// => "hello from component!"

const app = Vue.createApp({
myOption: 'hello!'
})

// inject a handler for `myOption` custom option
app.mixin({
created() {

const myOption = this.$options.myOption

if (myOption) {

console.log(myOption)

}
}
})

// add myOption also to child component
app.component('test-component', {
myOption: 'hello from component!'
})

app.mount('#mixins-global')

// => "hello!"
// => "hello from component!"
我们可以看到,对于自定义选项这不是简单的替换,而是分别调用,当然我们也可以制定我们自己的合并策略:
const app = Vue.createApp({})

app.config.optionMergeStrategies.customOption = (toVal, fromVal) => {
// return mergedVal
}

const app = Vue.createApp({})

app.config.optionMergeStrategies.customOption = (toVal, fromVal) => {
// return mergedVal
}
合并策略接收两个参数,分别是指定项在父实例和子实例的值,当使用mixin的时候我们可以查看打印什么:
const app = Vue.createApp({
custom: 'hello!'
})

app.config.optionMergeStrategies.custom = (toVal, fromVal) => {
console.log(fromVal, toVal)
// => "goodbye!", undefined
// => "hello", "goodbye!"
return fromVal || toVal
}

app.mixin({
custom: 'goodbye!',
created() {

console.log(this.$options.custom) // => "hello!"
}
})

const app = Vue.createApp({
custom: 'hello!'
})

app.config.optionMergeStrategies.custom = (toVal, fromVal) => {
console.log(fromVal, toVal)
// => "goodbye!", undefined
// => "hello", "goodbye!"
return fromVal || toVal
}

app.mixin({
custom: 'goodbye!',
created() {

console.log(this.$options.custom) // => "hello!"
}
})
可以看到第一次从mixin打印,然后从app打印。注意事项注意事项

mixin很容易造成冲突,你得确保不会有冲突的属性名,来避免冲突,这会造成额外的负担

复用性有限,因为mixin不能接受参数,所以逻辑是写定的,不灵活
mixin很容易造成冲突,你得确保不会有冲突的属性名,来避免冲突,这会造成额外的负担复用性有限,因为mixin不能接受参数,所以逻辑是写定的,不灵活所以官方推荐使用 Composition Api来组织逻辑Composition Api以上就是详解Vue的mixin策略的详细内容,关于Vue的mixin策略的资料请关注其它相关文章!