likes
comments
collection
share

mixin混入

作者站长头像
站长
· 阅读数 49

什么是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')

运行结果

mixin混入

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

局部的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')

运行结果

mixin混入

结果显示: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
评论
请登录