Skip to content

mixin 混入

在Vue.js中,Mixin(混入)是一种用于在多个组件之间共享可重用功能的方式。通过使用Mixin,可以将一些通用的逻辑、方法或生命周期钩子等混入到多个组件中,从而减少重复代码并提高代码的复用性。下面是使用Mixin的基本步骤:

单个组件混入

  1. 创建Mixin: 在Vue应用中,创建一个Mixin对象,其中包含需要共享的逻辑、方法或生命周期钩子。例如,可以创建一个名为exampleMixin的Mixin对象:
js
// mixin.js
export const exampleMixin = {
    data() {
        return {
            count: 0,
            msg: "我是mixin 数据"
        };
    },
    computed: {
        userInfo() {
            // 从vuex 或者 localStorage读取
            return { username: "张三", age: 20 }
        }
    },
    created() {
        console.log("我是mixin中的created生命周期函数");
    },
    mounted() {
        console.log("我是mixin中的mounted生命周期函数");
    },
    methods: {
        increment() {
            this.count++;
        },
    },
};
  1. 使用Mixin: 在需要使用Mixin的组件中,通过mixins选项将Mixin混入到组件中。可以在单个组件中混入一个或多个Mixin。
vue
// App.vue
<template>
  <div id="app">
    读取计算属性的内容:姓名:{{ userInfo.username }} / 年龄:{{ userInfo.age }}
    <div>
      count:{{ count }}
      <button @click="add">add+1</button>
    </div>
  </div>
</template>

<script>
import { exampleMixin } from './mixin'
export default {
  name: 'App',
  mixins: [exampleMixin],
  comments: {},
  methods: {
    add() {
      this.increment()
    }
  },
  created() {
    console.log("组件调用minxi数据", this.msg);
  },
  mounted() {
    console.log("我是组件的mounted生命周期函数")
  }
}
</script>

现在,组件就具有了exampleMixin中定义的count数据和increment方法。

并且可以在mixin中混入生命周期钩子,执行公共的方法。

image-20230611125405236

全局混入

上一点我们使用mixin是在需要的组件中引入它,我们也可以在全局先把它注册好,这样我们就可以在任何组件中直接使用了。

js
import Vue from "vue";
import App from "./App.vue";
import { exampleMixin } from "./mixin";
Vue.mixin(exampleMixin); // 全局混入mixin ,每个组件都会生效

Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App),
}).$mount("#app");

Mixin的合并规则

  1. 当组件和Mixin具有相同的选项时,Vue会根据一定的规则进行合并。一般情况下,数据对象、方法和生命周期钩子会按照一定的顺序进行合并。
  2. 如果遇到冲突,组件的选项将覆盖Mixin的选项。 详细的合并规则可以参考Vue文档中的Mixin部分

data数据冲突

当mixin中的data数据与组件中的data数据冲突时,组件中的data数据会覆盖mixin中数据,借用官方的一段代码:

javascript
var mixin = {
  data: function () {
    return {
      message: 'hello',
      foo: 'abc'
    }
  }
}

new Vue({
  mixins: [mixin],
  data: function () {
    return {
      message: 'goodbye',
      bar: 'def'
    }
  },
  created: function () {
    console.log(this.$data)
    // => { message: "goodbye", foo: "abc", bar: "def" }
  }
})

可以看到最终打印的message是组件中message的值,其它没有冲突的数据自然合并了。

方法冲突

这种冲突很容易遇到,毕竟大家命名方法的名字很容易一样,这里同样借用官方的一段代码:

javascript
var mixin = {
  methods: {
    foo: function () {
      console.log('foo')
    },
    conflicting: function () {
      console.log('from mixin')
    }
  }
}

var vm = new Vue({
  mixins: [mixin],
  methods: {
    bar: function () {
      console.log('bar')
    },
    conflicting: function () {
      console.log('from self')
    }
  }
})

vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"

上段代码中mixin和组件中都有conficting方法,但是最终在组件中调用时,实际调用的是组件中的conflicting方法。

mixin的优缺点

优点

  • 提高代码复用性
  • 无需传递状态
  • 维护方便,只需要修改一个地方即可

缺点

  • 命名冲突
  • 滥用的话后期很难维护
  • 不好追溯源,排查问题稍显麻烦
  • 不能轻易的重复代码

总结

使用Mixin的好处是可以将通用的逻辑和代码复用在多个组件中,提高了代码的可维护性和可复用性。然而,使用Mixin也需要注意避免命名冲突和组件与Mixin之间的耦合度过高,以免导致代码混乱和不可预测的行为。

前端知识体系 · wcrane