在日常的开发中,我会遇到在不同的组件中经常会需要用到一些相同或者相似的代码,这些代码的功能相对独立。这时,我们可以通过Vue的mixin功能将相同或者相似的代码提出,这样一来既方便了代码的复用也使得维护更加容易。
这篇文章将为你讲述 Vue mixin的使用方法,让你对mixin有更深入的了解。
一、mixin是什么
官方文档
混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
民间解释
我们在开发组件的过程中,常常会遇到一些具有相同逻辑和功能的组件。
如果每个组件各写一套方法会导致代码冗余,后期更改的时候也要一个个的改非常的浪费时间和精力。
mixins就是将这些多个相同的逻辑抽离出来,各个组件只需要引入mixins,就能实现一次写代码,多组件受益的效果。
二、使用方法
先定义mixin:在src目录下新建mixin文件夹,然后新建index.js文件,该文件存放我们的mixin代码。
export const mixins = {
data() {
return {};
},
computed: {},
created() {},
mounted() {},
methods: {}
};
局部混入
在组件中引入mixin,然后使用mixins
<script>
import mixin from '@/mixin/index.js';
export default {
mixins:[mixin],
}
</script>
全局混入
在初始化Vue之前(main.js中)调用Vue.mixin()进行全局混入
import Vue from "vue";
import App from "./App.vue";
import { mixins } from "./mixin/index";
Vue.mixin(mixins);
Vue.config.productionTip = false;
new Vue({
render: (h) => h(App),
}).$mount("#app");
注意
不同组件中的mixin是相互独立的。
官方提示:请谨慎使用全局混入,因为它会影响每个单独创建的Vue实例(包括第三方组件)。
三、使用场景
在开发中,经常会遇到在不同的组件中用到相同或者相似的代码,这些代码的功能相对独立;就可以利用mixins将公共部分提取出来,通过 mixins封装的函数,组件调用他们是不会改变函数作用域外部的。
例子:使用mixin做一个button组件
1.自定义一个组件叫做mybutton.vue
<template>
<button type="button" class="mybtn" :class="[d_name]">
<!-- 这里的文字需要使用插槽,让用户自定义 -->
<slot></slot>
</button>
</template>
<script>
export default {
props: {
d_name: String
}
}
</script>
<style scoped>
.mybtn {
border: none;
padding: 5px 8px;
outline: none;
background: none;
color: black;
}
.mybtn.primay {
background-color: blue;
color: white;
}
.mybtn.danger {
background-color: red;
color: white;
}
.mybtn.success {
background-color: green;
color: white;
}
</style>
2.定义一个myui文件夹,编写index.js存放mixin代码
import mybutton from './mybutton.vue'
export default {
components: { mybutton }
}
3.局部引入(建议)
<template>
<div class="home">
<!-- <div class="con"><tab></tab></div> -->
<mybutton>BUTTON</mybutton>
<mybutton d_name="success">BUTTON1</mybutton>
<mybutton d_name="danger">BUTTON2</mybutton>
<mybutton d_name="primay">BUTTON3</mybutton>
</div>
</template>
<script>
import btnMix from '../libs/myui/index.js'
export default {
name: 'Home',
// 这是一种局部的混合
mixins: [btnMix],
}
</script>
有兴趣的同学也可以试试全局引入。
四、注意事项
1. mixin对象的data数据与组件选项会进行合并,如果有冲突,组件优先级高于mixin。
export const mixin = {
data: function () {
return {
message: 'hello',
foo: 'foo'
}
}
}
new Vue({
mixins: [mixin],
data: function () {
return {
message: 'world',
bar: 'bar'
}
},
created: function () {
console.log(this.$data)
}
})
输出结果为:
{ message: "world", foo: "foo", bar: "bar" }
2.mixin和组件中存在相同方法时,组件的方法的优先级大于mixin中。
也就是,mixin中方法会被组件中的方法覆盖掉,不执行。属性与方法一致。
export const mixin = {
methods: {
tryMixin() {
console.log('mixin的方法');
}
}
}
new Vue({
mixins: [mixin],
methods: {
tryMixin() {
console.log('组件的方法');
}
}
})
输出结果为:
'组件的方法'
3. mixin的事件执行顺序要优先于组件的。
也就是,mixin在所有生命周期事件中都要优先于组件方法。
export const mixin = {
mounted() {
console.log('mixin', 'mounted');
}
};
export default {
mixins: [mixin],
mounted() {
console.log('sub-model', 'mounted');
}
};
输出结果为:
'mixin', 'mounted'
'sub-model', 'mounted'
4.多个组件调用同一个mixin,每个变量都是单独独立的,不会项目污染改变变量。
export const mixins = {
data() {
return {
age: 18,
}
},
mounted() {
this.getAge()
},
methods: {
getAge() {
console.log(this.age)
}
}
// 组件1对age进行+1操作
export default {
mixins: [myMixins],
data() {
return {}
},
created() {
this.age++
},
}
// 组件2对不进行任何操作
export default {
mixins: [myMixins],
data() {
return {}
},
}
切换两个页面,输出结果为:
19
18
发现组件1改变了age里面的值,组件2中age值还是混合对象的初始值,并没有随着组件1的增加而改变。
5. Vue3 Hooks代替了Vue2 Mixins。
vue3 中的 hooks 就是函数的一种写法,就是将文件的一些单独功能的js代码进行抽离出来,放到单独的js文件中,或者说是一些可以复用的公共方法/功能。其实 hooks 和 vue2 中的 mixin 有点类似,但是相对 mixins 而言, hooks 更清楚复用功能代码的来源, 更清晰易懂。
import { ref, onMounted, onUnmounted } from "vue";
export function useMousePosition() {
const x = ref(0);
const y = ref(0);
function update(e) {
x.value = e.pageX;
y.value = e.pageY;
}
onMounted(() => {
window.addEventListener("mousemove", update);
});
onUnmounted(() => {
window.removeEventListener("mousemove", update);
});
return { x, y };
}
在组件中使用
import { useMousePosition } from "./mouse";
export default {
setup() {
const { x, y } = useMousePosition();
// other logic...
return { x, y };
},
};
五、mixin优缺点
优点:
提高代码复用性
无需传递状态
维护方便,只需要修改一个地方即可
缺点:
命名冲突
滥用的话后期很难维护
不好追溯源,排查问题稍显麻烦
总结
mixin给我们提供了方便的同时也给我们带来了灾难,所以有很多时候不建议滥用它,但是在有些场景下使用它又是非常合适的,这就得根据自己来取舍了。所以在很多时候我们需要考虑用公共组件还是使用mixin。