浅析vue混入(mixin)

  vue中的混入,可以在一定程度上提高代码的复用性。通俗来说,混入类似于“继承”,当前组件对象继承于组件对象,一般情况下遵循“就近原则”。但是与继承不同的是,继承一般都跟随者属性的重写与合并,混入在不同的配置项中,有着不同的混入策略,下面会一一进行介绍vue不同配置项的混入策略。vue混入的基本流程如图所示,混入属性的合并是发生在组件的生命周期钩子调用之前的。

  

   vue中,混入实现的主要代码如下:

 1 export function mergeOptions (
 2   parent: Object,
 3   child: Object,
 4   vm?: Component
 5 ): Object {
 6   if (process.env.NODE_ENV !== 'production') {
 7     // 检测组件名称是否合法
 8     checkComponents(child)
 9   }
10 
11   if (typeof child === 'function') {
12     child = child.options
13   }
14   // 格式化属性名称
15   normalizeProps(child, vm)
16   // 格式化依赖注入内容
17   normalizeInject(child, vm)
18   // 格式化指令内容
19   normalizeDirectives(child)
20 
21   // Apply extends and mixins on the child options,
22   // but only if it is a raw options object that isn't
23   // the result of another mergeOptions call.
24   // Only merged options has the _base property.
25   // 只有合并的options拥有_base属性
26   // 需要递归进行合并属性
27   // 首先合并extends和mixins
28   if (!child._base) {
29     if (child.extends) {
30       parent = mergeOptions(parent, child.extends, vm)
31     }
32     if (child.mixins) {
33       for (let i = 0, l = child.mixins.length; i < l; i++) {
34         parent = mergeOptions(parent, child.mixins[i], vm)
35       }
36     }
37   }
38 
39   const options = {}
40   let key
41   for (key in parent) {
42     mergeField(key)
43   }
44   for (key in child) {
45     if (!hasOwn(parent, key)) {
46       mergeField(key)
47     }
48   }
49   // 合并属性
50   function mergeField (key) {
51     // 获取属性的合并策略
52     const strat = strats[key] || defaultStrat
53     // 调用属性合并策略,返回值为属性合并结果
54     options[key] = strat(parent[key], child[key], vm, key)
55   }
56   return options
57 }

  具体某个字段的合并,调用的是mergeField方法,此方法主要是获取代码混入策略,返回值作为混入的结果。通过调试我们可以看出,混入的策略对象中包含我们常见的vue属性,如下所示:

  

   混入的实现,采用了策略模式的设计模式,在对组件数据初始化时,会遍历组件的配置文件,根据配置文件,调用对应的策略方法。如果组件中存在不是vue指定的配置,就是策略类strats中不包含的属性,就会调用默认的合并方法defaultStrat,该方法的定义如下:

/**
 * Default strategy.
 * 默认的属性合并策略,采用就近原则,如果子级没有,就采用父级的
 */
const defaultStrat = function (parentVal: any, childVal: any): any {
  return childVal === undefined
    ? parentVal
    : childVal
}

  strats是从哪来的呢? strats读取的是用户自定义配置。在项目初始化时,会初始化所有的属性合并策略,如下图所示:

  未完待续。。。。。。

   

猜你喜欢

转载自www.cnblogs.com/gerry2019/p/11889050.html