mixin

使用示例:

dist/2.mixin.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <div id="app" style="color: red; background: yellow">
    </div>
    <script src="<https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js>"></script>
    <script>
      // Vue.mixin 混合 可以混入一些公共方法

      // **1. 第一次(初始化时): Vue.options = {} 此刻下边加了个 mixin 的 created: {created(){}}**
      Vue.mixin({
        // data() {
        //   return { xxx: 10000 } // mixin 一般不用来定义数据,容易造成数据来源不明
        // }
        created() {
          console.log(`mixin1-created`);
        }
      });
      // **2. 第二次: Vue.options = {created:[fn]} 此刻下边又加了个 mixin 的 created: {created(){}}**
      Vue.mixin({
        created() {
          console.log(`mixin2-created`);
        }
      });
      // **3. 经过上边两步: Vue.options = { created: [fn, fn] }**
      // **mixin 内部会将多个 created 合并成一个队列 依次执行**
      const vm = new Vue({
        el: '#app',
        data: {
          name: 'lance',
          age: 20,
          address: {
            name: 30,
            content: '苦咖啡'
          },
          hobby: ['eat', 'drink', { a: 1 }]
        },
        created() {
          // console.log(`created:`, this.xxx); // 数据来源不明确
          console.log(`created`);
        }
      });
    </script>
  </body>
</html>

Vue 将混入的 created 合并到了 Vue.options 上:

image.png

mixin: 发布订阅模式

这就是一个典型的发布订阅,Vue 把所有的生命周期都订阅好,等到了适当的时机,再依次触发。

实现思路

1. 全局配置与局部配置的合并

Vue.mixin 的核心作用是将全局的 mixin 选项局部组件的选项合并。为了实现这一点,Vue 需要一个合并策略来处理不同类型的选项,例如生命周期钩子、数据、方法等。Vue 的生命周期钩子需要进行特殊处理:多个 mixin 的生命周期钩子需要按顺序依次执行。

2. 策略模式的使用

为了更灵活地处理不同类型的选项,Vue 使用了策略模式。Vue 中的 strats(策略对象)包含了针对不同类型的选项的合并策略,比如:

3. 生命周期钩子函数的特殊处理

Vue 的生命周期钩子(如 createdmounted 等)在合并时,如果全局 mixin 和局部组件中都有定义,则会将它们合并为一个数组,确保所有的钩子函数都能在组件生命周期的特定阶段依次执行。

具体来说: