详解Vue 中 extend 、component 、mixins 、extends 的区别(2)
从结果上看,三种方式都能实现需求,但是形式却有不同.
- Vue.extend
- Vue.extend只是创建一个构造器,他是为了创建可复用的组件.
- mixins,extends
- 而mixins和extends是为了拓展组件.
从源码来看通过extend,extends和mixins三种方式接收的options,最终都是通过mergeOptions进行合并的.差异只是官方文档中提到的优先级不同extend > extends > mixins. 所以,如果是简单的扩展组件功能,三个方式都可以达到目的.
而这三种方式使用场景上细化的区分,目前我也蒙圈中...
//几种方式的不同示例:
https://jsfiddle.net/willnewi...
选项对象合并策略 Vue.config.optionMergeStrategies
上面提到的选项对象,是在mergeOptions中按照一定策略进行合并的.
打印Vue.config.optionMergeStrategies,你会看默认的optionMergeStrategies如下:
- mergeHook
- 子组件和父组件的生命周期事件会合并在一个数组里。父组件在前,子组件在后。
- watch
- 子组件和父组件的watchers会合并在一个数组里。父组件在前,子组件在后。
- mergeAssets(filters,components,directives)
- 首先会在子组件里查找,如果没有,才会沿着原型链向上,找父组件中对应的属性。
- data 合并规则
- 无重复的属性保留
- 同名覆盖
- data中的对象也是相同规则,无重复的属性保留,同名覆盖
- props、methods、computed: 无重复保留,同名子组件覆盖父组件
mergeAssets
mergeAssets合并方法里,用到了原型委托.他会先把父组件的属性放在创建的新对象的原型链上.然后扩展新对象
对象里查找属性的规则 :举个例子,当查找一个属性时,如 obj[a] ,如果 obj 没有 a 这个属性,那么将会在 obj 对象的原型里找,如果还没有,在原型的原型上找,直到原型链的尽头,如果还没有找到,返回 undefined。
function extend (to, _from) { for (var key in _from) { to[key] = _from[key]; } return to } function mergeAssets (parentVal, childVal) { var res = Object.create(parentVal || null); return childVal ? extend(res, childVal) : res }
总结
- Vue.component 注册全局组件,为了方便
- Vue.extend 创建组件的构造函数,为了复用
- mixins、extends 为了扩展