mixins 是 Vue2 OptionsAPI 的产物,在 Vue3 的版本中已经不再推荐使用了。
    mixins 应用场景是当两个或多个组件的某些数据、逻辑相同的时候,可以把这些相同的数据、逻辑抽离为一个单独的 JS 文件,该 JS 文件内和 SFC 文件中的<script>结构是一样的,都是导出一个模块。

    1. export default{
    2. // 共用的 data 数据
    3. data(){
    4. return{
    5. title: "This is test title."
    6. }
    7. },
    8. // 公共的逻辑处理
    9. methods:{
    10. onCliclAdd(){
    11. console.log("This is test methods.")
    12. }
    13. }
    14. }

    然后我们在需要复用的组件内部通过mixins属性进行注册,就实现了混入!

    1. <template>
    2. <!-- 可以直接调用 test.js 混入的方法 -->
    3. <button @click="onCliclAdd">Add btn</button>
    4. </template>
    5. <script>
    6. import testMixin from "./mixins/test.js";
    7. export default{
    8. name:"App",
    9. // 通过数组的方式注册,所以一个组件可以注册多个 mixin
    10. mixins: ['testMixin'],
    11. mounted(){
    12. // 可以直接调用混入文件的数据
    13. console.log(this.title);
    14. }
    15. }
    16. </script>

    当然,mixins 和 component 一样,可以进行全局注册,但这不是被推荐的:

    1. import { createApp } from "vue";
    2. import App from "./App.vue";
    3. import testMixin from "./mixins/test"
    4. const app = createApp(App);
    5. app.mixin(testMixin);
    6. app.mount("#app");

    因为混入文件的数据、逻辑会和普通组件内的数据、逻辑混合在一块,所以混入的时候会存在对应的规则:
    1、当组件内部有的数据,mixins 不会进行覆盖。
    也就是说,当选项中的 data 有冲突的时候,组件内的 data 优先!

    1. <template>
    2. <div>
    3. <h1>{{ title }}</h1>
    4. <p>{{ author }}</p>
    5. <p>{{ content }}</p>
    6. </div>
    7. </template>
    8. <script>
    9. import mixinTest from "../mixins/test";
    10. export default {
    11. name: "App",
    12. mixins: [mixinTest],
    13. data() {
    14. return {
    15. title: "This is test 1.",
    16. content: "This is content 1."
    17. };
    18. }
    19. };
    20. </script>
    1. export default {
    2. data() {
    3. return {
    4. title: "This is mixin title.",
    5. author: "This is mixin author.",
    6. content: "This is mixin content."
    7. };
    8. }
    9. };

    结果如下:
    image.png
    优选使用组件内部的 title 和 content,组件内部没有 author 才会去使用 mixins 文件的 author。

    2、当组件和 mixins 文件有相同钩子函数的时候,优先执行 mixins 的钩子函数。

    1. <script>
    2. import mixinTest from "../mixins/test";
    3. export default {
    4. name: "App",
    5. mixins: [mixinTest],
    6. mounted() {
    7. console.log("This is test1 mounted calling.");
    8. console.log(this);
    9. }
    10. };
    11. </script>
    1. export default {
    2. mounted() {
    3. console.log("This is Mixin mounted calling.");
    4. }
    5. };

    结果如下:
    image.png

    3、mixins 文件内的相关 options 会合并到组件实例对象上!

    1. <template>
    2. <div>
    3. <h1>{{ title }}</h1>
    4. <p>{{ author }}</p>
    5. <p>{{ content }}</p>
    6. <button @click="doComponent">btn</button>
    7. </div>
    8. </template>
    9. <script>
    10. import mixinTest from "../mixins/test";
    11. export default {
    12. name: "App",
    13. mixins: [mixinTest],
    14. data() {
    15. return {
    16. title: "This is test 1.",
    17. content: "This is content 1."
    18. };
    19. },
    20. mounted() {
    21. console.log("This is test1 mounted calling.");
    22. console.log(this);
    23. },
    24. methods: {
    25. doComponent() {
    26. console.log("doComponent");
    27. }
    28. }
    29. };
    30. </script>
    1. export default {
    2. data() {
    3. return {
    4. title: "This is mixin title.",
    5. author: "This is mixin author.",
    6. content: "This is mixin content."
    7. };
    8. },
    9. mounted() {
    10. console.log("This is Mixin mounted calling.");
    11. },
    12. methods: {
    13. doMixin() {
    14. console.log("doMixin");
    15. }
    16. }
    17. };

    结果如下:
    image.png
    会把 mixins 内的 data、methods 合并到组件实例上面。

    4、当组件内和 mixins 文件有同名方法时候,优先执行组件内部的方法。

    1. <template>
    2. <div>
    3. <!-- 省略其他内容 -->
    4. <button @click="doComponent">btn</button>
    5. </div>
    6. </template>
    7. <script>
    8. import mixinTest from "../mixins/test";
    9. export default {
    10. name: "App",
    11. mixins: [mixinTest],
    12. methods: {
    13. doComponent() {
    14. console.log("doComponent");
    15. }
    16. }
    17. };
    18. </script>
    1. export default {
    2. methods: {
    3. doComponent() {
    4. console.log("doMixinComponent");
    5. }
    6. }
    7. };

    结果如下:
    image.png

    mixins 的缺点:
    1、当一个 mixins 文件被多个组件注册的时候,可能会多出很多非必要的选项或者属性,可能为了满足需求,导致把 mixin 文件进行无限的拆分,也有可能导致命名冲突;
    2、因为 mixins 导出的是一个对象,没有办法通过函数那样通过参数去控制哪些参数是需要的,哪些是不需要的,这极大的干扰了 mixins 的合理性复用,所以 Vue3 不建议使用,而是使用 CompositionAPI。所有需要复用、集成的功能全部封装为函数,该函数内部可以使用 Vue3 提供的相关 API,例如 watch、ref 等等…