mixin混入
什么是mixin
将一个组件配置对象放到组件里
如何使用mixin
1. 定义
const myMixin = {
data(){
return {
number: 2
}
}
}
2. 使用
mixins:[myMixin]
mixin中的数据和组件中数据的优先级
1. data
组件data优先级高于mixin data 优先级
【敲代码】
// mixin混入
const myMixin = {
data(){
return {
number: 2
}
}
}
const app = Vue.createApp({
data() {
return {
number: 1,
}
},
mixins:[myMixin],
methods:{
handleClick(){
console.log('click');
}
},
template: `
<div>
<div>{{number}}</div>
<button @click="handleClick">增加</button>
</div>
`
})
const vm = app.mount('#root')
备注
当根组件中引入mixin中data后,如果根组件中有这个data,那么模板中就优先使用根组件中的data,即number:1
。如果根组件中没有data,就使用mixin中的data
2. 生命周期函数
先执行mixin里面的生命周期函数,再执行组件中的生命周期函数
【敲代码】
// mixin混入
const myMixin = {
data(){
return {
number: 2,
count: 333
}
},
created(){
console.log('mixin created');
}
}
const app = Vue.createApp({
data() {
return {
number: 1,
}
},
created(){
console.log('根组件 created');
},
mixins:[myMixin],
methods:{
handleClick(){
console.log('click');
}
},
template: `
<div>
<div>{{number}}</div>
<div>{{count}}</div>
<button @click="handleClick">增加</button>
</div>
`
})
const vm = app.mount('#root')
【运行结果】
3. methods
组件中的方法的优先级高于mixin中方法的优先级
【敲代码】
// mixin混入
const myMixin = {
data(){
return {
number: 2,
count: 333
}
},
created(){
console.log('mixin created');
},
handleClick(){
console.log('mixin click');
}
}
const app = Vue.createApp({
data() {
return {
number: 1,
}
},
created(){
console.log('根组件 created');
},
mixins:[myMixin],
methods:{
handleClick(){
console.log('根组件 click');
}
},
template: `
<div>
<div>{{number}}</div>
<div>{{count}}</div>
<button @click="handleClick">增加</button>
</div>
`
})
const vm = app.mount('#root')
【运行结果】
局部的mixin
上面使用mixin的方式是局部定义的mixin
局部的mixin同局部组件要在compinents中注册才能使用一样,局部的mixin也要在mixins中引用才能使用
注意
局部注册的组件,在使用的时候只能在组件的最外层使用,如果这个组件中使用了子组件,那么子组件中是不能使用这个mixin的
【敲代码】
// mixin混入
const myMixin = {
data(){
return {
number: 2,
count: 333
}
},
created(){
console.log('mixin created');
},
handleClick(){
console.log('mixin click');
}
}
const app = Vue.createApp({
data() {
return {
number: 1,
}
},
created(){
console.log('根组件 created');
},
mixins:[myMixin],
methods:{
handleClick(){
console.log('根组件 click');
}
},
template: `
<div>
<div>{{number}}</div>
<child/>
<button @click="handleClick">增加</button>
</div>
`
})
app.component('child',{
mixins:[myMixin],
template: `<div>{{count}}</div>`
})
const vm = app.mount('#root')
【运行结果】
结果显示:child中引用的变量count找不到,原因是局部注册的mixin只能在组件模板的最外层中使用,子组件如果想要使用,子组件就要自己使用mixins:[myMixin]
引入进来
全局的mixin
同全局组件类似,默认会注入到每个组件中,每个组件不需要像局部的mixin那样,在各个组件中都需要单独的使用mixins:[myMixin]
去引用
使用方法:
app.mixin({...})
【敲代码】
const app = Vue.createApp({
data() {
return {
number: 1,
}
},
created() {
console.log('根组件 created');
},
methods: {
handleClick() {
console.log('根组件 click');
}
},
template: `
<div>
<div>{{number}}</div>
<child/>
<button @click="handleClick">增加</button>
</div>
`
})
// 全局的mixin
app.mixin({
data() {
return {
number: 2,
count: 333
}
},
created() {
console.log('mixin created');
},
handleClick() {
console.log('mixin click');
}
})
app.component('child', {
template: `<div>{{count}}</div>`
})
const vm = app.mount('#root')
不推荐使用,代码的可维护性不高
自定义属性
直接定义在组件最外层对象上的属性,叫自定义属性,如下面的自定义属性number
const app = Vue.createApp({
number: 1,
template: `
<div>
<div>{{this.$options.number}}</div>
</div>
`
})
关于options:vue组件上所有的内容经过vue的处理后都会被放到$options
上,直接获取number是获取不到的,但是通过$options
获取可以
优先级
组件的自定义属性优先级高于mixin自定义属性的优先级
【敲代码】
const myMixin = {number: 2}
const app = Vue.createApp({
number:1,
mixins:[myMixin],
template: `
<div>
<div>{{this.$options.number}}</div>
</div>
`
})
修改自定义属性优先级
假如:现在希望mixin中的自定义属性的优先级要高于组件中的自定义属性的优先级
// 对自定义属性number的合并策略做出修改
app.config.optionMergeStrategies.number = (mixinVal,appValue) => {
}
其中mixinVal是mixin中的自定义属性,appValue是组件中的自定义属性
【敲代码】
const myMixin = {number: 2}
const app = Vue.createApp({
number:1,
mixins:[myMixin],
template: `
<div>
<div>{{this.$options.number}}</div>
</div>
`
})
// 对自定义属性number的合并策略做出修改
app.config.optionMergeStrategies.number = (mixinVal,appVal) => {
return mixinVal || appVal
}
const vm = app.mount('#root')
备注:mixin存在的不足
- 逻辑上看起来不那么直观清晰,需要到各种地方找mixin
- 如果出现问题不仅要到组件中查找问题,还要到mixin中查找问题,甚至还要看组件和mixin中是否存在冲突(如优先级的问题),因此定位错误也不是那么容易
- 全局的mixin中的数据,在其他地方使用这个数据的时候,可能因为时间长了不知道这个数据是哪里来的
- Vue3出来以后建议使用composition API,因为它的可维护性更高一点,或者使用插件来替代mixin
转载自:https://juejin.cn/post/7244420765800562725