混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
局部混入
个人理解:其实就相当于你创建了一个公共的类,当哪个组件需要用到这个类时就通过mixin将其引入。
<body>
<div id="app">
{{ msg }}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const myMixin = {
data() {
return {
msg: 'jerry',
}
},
methods: {
say() {
console.log("I'm myMixin");
}
},
created() {
this.say();
},
}
new Vue({
el: '#app',
data: {
msg: 'tom'
},
created() {
console.log('hello mixin');
},
mixins: [myMixin]
})
</script>
</body>
选项合并
当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”。
比如,数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。
同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。
值为对象的选项,例如 methods、components 和 directives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。
所以上面的最终msg的显示结果是tom,而打印的先后顺序是先打印混入对象中的I'm myMixin,再打印hello mixin。
注意:Vue.extend() 也使用同样的策略进行合并。
全局混入
可通过Vue.mixin({})创建全局混入,但是使用全局有一个缺点,就是所有的组件实例创建时都会调用它,了解即可。
mixin混入技术的应用
场景:现在有一个模态框和一个提示框,它们的样式、用法都不一样,但是展示的逻辑是一样的,都是通过改变boolean值进行展示。
这个时候我们就可以用到我们的mixin混入技术,将公共的isShow属性和handleToggle()处理方法提取出来,放入到一个局部的mixin对象中,然后分别在两个框的组件中将其引入。
<body>
<div id="app">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const toggleShow = {
data() {
return {
isShow: false
}
},
methods: {
handleToggle() {
this.isShow = !this.isShow;
}
},
}
const Modal = {
template: `
<div v-if='isShow'>
<h2>模态框组件</h2>
</div>
`,
mixins: [toggleShow]
}
const Tips = {
template: `
<div v-if='isShow'>
<h3>提示框组件</h3>
</div>
`,
mixins: [toggleShow]
}
new Vue({
el: '#app',
components: {
Modal, Tips
},
template: `
<div>
<button @click='handleModal'>模态框</button>
<button @click='handleTips'>提示框</button>
<Modal ref='modal'></Modal>
<Tips ref='tips'></Tips>
</div>
`,
methods: {
handleModal() {
this.$refs.modal.handleToggle();
},
handleTips() {
this.$refs.tips.handleToggle();
}
}
})
</script>
</body>
使用mixin混入技术的好处
避免了重复性代码,符合编程的dry原则。