Vue Mixin

Mixin是什么?

Mixin本质是一个JavaScript对象,它可以包含Vue组件中的datacomponentsmethodscomputed选项等。Mixin是一个类,其他类可以访问Mixin类的方法而不必成为它的之类。Mixin常用于功能模块使用,在需要该功能时混入,提高代码的复用性。

基础

首先创建mixin.js

1
2
3
4
5
6
7
8
9
10
11
12
13
// @/src/utils/mixin.js
const myMixin = {
created() {
this.hello()
},
methods: {
hello() {
console.log('hello from mixin!')
}
}
}

export default myMixin;

然后在组件中导入并使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// @/src/views/mixin.vue
import { reactive, toRefs } from 'vue'
import myMixin from '../utils/mixin'

export default {
setup() {
const state = reactive({
count: 0,
})

return {
...toRefs(state),
}
},
mixins: [myMixin]
}

在组件被创建时,可以看到hello from mixin!被打印了

选项合并

当组件和mixin对象含有同名选项时,这些选项将以恰当的方式进行合并。

mixin可以拥有自己的data函数,当mixin里的data函数里的数据与组件data的数据发生冲突,会以组件自身的数据为优先。

1
2
3
4
5
6
7
8
9
10
// @/src/utils/mixin.js
const myMixin = {
data(){
return{
message:"foo"
}
}
}

export default myMixin;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// @/src/views/mixin.vue
import myMixin from '../utils/mixin'

export default {
data(){
return{
message:"bar"
}
},
created() {
console.log(this.message) // bar
},
mixins: [myMixin]
}

值为对象的选项,例如 methodscomponentsdirectives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。

全局Mixin

可以为Vue组件全局应用Mixin

1
2
3
4
5
6
7
8
9
10
import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)
app.mixin({
created() {
console.log("hello")
}
})
app.mount('#app') // hello

Mixin可以全局注册,一旦使用全局Mixin,它将影响每一个之后创建的组件,包括每一个子组件。

自定义选项合并

自定义选项在合并时,默认策略为简单的覆盖已有值,如果想让某个自定义选项以自定义逻辑进行合并,可以在app.config.optionMergeStrategies中添加一个参数

1
2
3
4
5
const app = Vue.createApp({})

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

上面的代码是optionMergeStrategies的默认写法,所以Mixin在合并选项后的值总是被组件的选项值,我们可以把策略更改为优先返回Mixin中的值:

1
2
3
const app = Vue.createApp({})

app.config.optionMergeStrategies.custom = (toVal, fromVal) => toVal || fromVal