mixins 是 Vue2 OptionsAPI 的产物,在 Vue3 的版本中已经不再推荐使用了。
mixins 应用场景是当两个或多个组件的某些数据、逻辑相同的时候,可以把这些相同的数据、逻辑抽离为一个单独的 JS 文件,该 JS 文件内和 SFC 文件中的<script>结构是一样的,都是导出一个模块。
export default{// 共用的 data 数据data(){return{title: "This is test title."}},// 公共的逻辑处理methods:{onCliclAdd(){console.log("This is test methods.")}}}
然后我们在需要复用的组件内部通过mixins属性进行注册,就实现了混入!
<template><!-- 可以直接调用 test.js 混入的方法 --><button @click="onCliclAdd">Add btn</button></template><script>import testMixin from "./mixins/test.js";export default{name:"App",// 通过数组的方式注册,所以一个组件可以注册多个 mixinmixins: ['testMixin'],mounted(){// 可以直接调用混入文件的数据console.log(this.title);}}</script>
当然,mixins 和 component 一样,可以进行全局注册,但这不是被推荐的:
import { createApp } from "vue";import App from "./App.vue";import testMixin from "./mixins/test"const app = createApp(App);app.mixin(testMixin);app.mount("#app");
因为混入文件的数据、逻辑会和普通组件内的数据、逻辑混合在一块,所以混入的时候会存在对应的规则:
1、当组件内部有的数据,mixins 不会进行覆盖。
也就是说,当选项中的 data 有冲突的时候,组件内的 data 优先!
<template><div><h1>{{ title }}</h1><p>{{ author }}</p><p>{{ content }}</p></div></template><script>import mixinTest from "../mixins/test";export default {name: "App",mixins: [mixinTest],data() {return {title: "This is test 1.",content: "This is content 1."};}};</script>
export default {data() {return {title: "This is mixin title.",author: "This is mixin author.",content: "This is mixin content."};}};
结果如下:
优选使用组件内部的 title 和 content,组件内部没有 author 才会去使用 mixins 文件的 author。
2、当组件和 mixins 文件有相同钩子函数的时候,优先执行 mixins 的钩子函数。
<script>import mixinTest from "../mixins/test";export default {name: "App",mixins: [mixinTest],mounted() {console.log("This is test1 mounted calling.");console.log(this);}};</script>
export default {mounted() {console.log("This is Mixin mounted calling.");}};
结果如下:
3、mixins 文件内的相关 options 会合并到组件实例对象上!
<template><div><h1>{{ title }}</h1><p>{{ author }}</p><p>{{ content }}</p><button @click="doComponent">btn</button></div></template><script>import mixinTest from "../mixins/test";export default {name: "App",mixins: [mixinTest],data() {return {title: "This is test 1.",content: "This is content 1."};},mounted() {console.log("This is test1 mounted calling.");console.log(this);},methods: {doComponent() {console.log("doComponent");}}};</script>
export default {data() {return {title: "This is mixin title.",author: "This is mixin author.",content: "This is mixin content."};},mounted() {console.log("This is Mixin mounted calling.");},methods: {doMixin() {console.log("doMixin");}}};
结果如下:
会把 mixins 内的 data、methods 合并到组件实例上面。
4、当组件内和 mixins 文件有同名方法时候,优先执行组件内部的方法。
<template><div><!-- 省略其他内容 --><button @click="doComponent">btn</button></div></template><script>import mixinTest from "../mixins/test";export default {name: "App",mixins: [mixinTest],methods: {doComponent() {console.log("doComponent");}}};</script>
export default {methods: {doComponent() {console.log("doMixinComponent");}}};
结果如下:
mixins 的缺点:
1、当一个 mixins 文件被多个组件注册的时候,可能会多出很多非必要的选项或者属性,可能为了满足需求,导致把 mixin 文件进行无限的拆分,也有可能导致命名冲突;
2、因为 mixins 导出的是一个对象,没有办法通过函数那样通过参数去控制哪些参数是需要的,哪些是不需要的,这极大的干扰了 mixins 的合理性复用,所以 Vue3 不建议使用,而是使用 CompositionAPI。所有需要复用、集成的功能全部封装为函数,该函数内部可以使用 Vue3 提供的相关 API,例如 watch、ref 等等…
