Vue3的mixin

1,124 阅读2分钟

小编在之前的项目中还没有接触过minxin(数据混入),直到一次面试的时候,面试官问我,我才注意到,原来还有这样的一个东西,今天小编就和大家一起看看这个神奇的mixin。个人感觉mixin和组件的注册和使用很类似,我们要注册一个局部的mixin的时候,可以这样。大家还可以关注我的微信公众号,蜗牛全栈。

// 组件data和methods优先级高于mixin中的data优先级,组件和mixin数据同时存在的时候,使用组件中的data数据,如果组件内部没有data,使用mixin中的数据
// 声明周期函数,先执行mixin里面的,再执行组件里面的生命周期函数
const myMinxin = {    
    data(){        
        return {            
            num: 2        
        }    
    },    
    created(){        
        console.log('mixin created')    
    },    
    methods:{        
        handleClick(){            
            console.log('mixin handleClick')        
        }    
    }
}

const app = Vue.createApp({    
    data(){        
        return {            
            num: 1        
        }    
    },    
    mixins:[myMinxin],    
    methods:{        
        handleClick(){            
            console.log('handleClick')        
        }    
    },    
    created(){        
        console.log('created')    
    },    
    template:`<div>{{ num }}</div>
            <button @click="handleClick">点击</button>`
    })
const vm = app.mount('#root')

之所以叫上面的组件为局部组件,是因为只能在哪个组件内注册,在哪个组件内部使用,在有子组件的时候,并不能获取到数据混入的数据,就像这样

const myMinxin = {    
    data(){        
        return {            
            num: 2,            
            count:66        
        }    
    },    
    created(){        
        console.log('mixin created')    
    },    
    methods:{        
        handleClick(){           
            console.log('mixin handleClick')        
        }    
}}

const app = Vue.createApp({   
    data(){        
        return {            
            num: 1        
        }    
    },    
    mixins:[myMinxin],    
    methods:{        
        handleClick(){            
            console.log('handleClick')        
        }    
    },    
    created(){        
        console.log('created')    
    },    
    template:`<div>{{ num }}</div>
            <child />
            <button @click="handleClick">点击</button>`
    })
app.component('child',{    
    template:`<div>{{ count }}</div>` 
    // 这个时候,就获取不到了,因为是在组件内部定义的,可以理解成局部的mixin。如果想用的话,需要在子组件中,也用一个mixin})
const vm = app.mount('#root')

类似组件,那我们想全局注册一个mixin,要怎么写呢?

const app = Vue.createApp({    
    data(){        
        return {            
            num: 1        
        }    
    },    
    methods:{        
        handleClick(){            
            console.log('handleClick')        
        }    
    },    
    created(){        
        console.log('created')   
    },    
    template:`<div>{{ num }}</div>
            <child />            
            <button @click="handleClick">点击</button>`
    })
app.component('child',{    
    template:`<div>{{ count }}</div>`})
    // 通过app.mixin注册全局mixin
    app.mixin({    
        data(){        
            return {            
                num: 2,            
                count:66        
            }    
        },   
        created(){        
            console.log('mixin created')    
        },    
        methods:{        
            handleClick(){            
                console.log('mixin handleClick')        
            }    
        }})
const vm = app.mount('#root')

从上面的几个例子,我们知道,不管是全局mixin还是局部mixin,如果组件和mixin中同时存在相同的数据,组件内的数据优先级总是高于mixin中的数据,那么有没有什么办法,让mixin内的数据优先级高于组件内呢,答案是肯定的,我们可以修改Vue的配置,就像这样

const myMinxin = {    
    num: 2
}
const app = Vue.createApp({    
    num: 1,    
    mixins:[myMinxin],    
    methods:{        
        handleClick(){            
            console.log('handleClick')        
        }    
    },    
    created(){        
        console.log('created')    
    },    
    template:`<div>{{ this.$options.num }}</div> 
    // this.$options.num            
    <button @click="handleClick">点击</button>`
})
// 修改num中的数据混入和data中的策略
app.config.optionMergeStrategies.num = (mixinVal,appValue) => {    
    return mixinVal || appValue
}
const vm = app.mount('#root')