在segmentfault上看到了一个问题vue.extend, vue.component 区别,忽然有些方,好歹也写了几个小vue项目,本身都弄不清楚这些东西...javascript
首先咱们来约定一个选项对象 baseOptions,后面的代码会用到.css
let options = { template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>', data: function () { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } }, created(){ console.log('onCreated-1'); } };
实例化一个组件.html
new Vue(baseOptions); // -> onCreated-1
Vue.component 是用来注册或获取全局组件的方法,其做用是将经过 Vue.extend 生成的扩展实例构造器注册(命名)为一个组件.全局注册的组件能够在全部晚于该组件注册语句构造的Vue实例中使用.vue
Vue.component('global-component', Vue.extend(baseOptions)); //传入一个选项对象(自动调用 Vue.extend),等价于上行代码. Vue.component('global-component', baseOptions); // 获取注册的组件(始终返回构造器) var MyComponent = Vue.component('my-component')
当咱们须要在其余页面‘扩展’或者叫‘混合’baseOptions时,Vue中提供了多种的实现方式:extend,mixins,extends.java
能够扩展 Vue 构造器,从而用预约义选项建立可复用的组件构造器。segmentfault
let BaseComponent = Vue.extend(baseOptions); //基于基础组件BaseComponent,再扩展新逻辑. new BaseComponent({ created(){ //do something console.log('onCreated-2'); } //其余自定义逻辑 }); // -> onCreated-1 // -> onCreated-2
mixins 选项接受一个混合对象的数组。这些混合实例对象能够像正常的实例对象同样包含选项,他们将在 Vue.extend() 里最终选择使用相同的选项合并逻辑合并。api
new Vue({ mixins: [baseOptions], created(){ //do something console.log('onCreated-2'); } //其余自定义逻辑 }); // -> onCreated-1 // -> onCreated-2
这和 mixins 相似,区别在于,组件自身的选项会比要扩展的源组件具备更高的优先级.数组
官方文档是这么写的,除了优先级,可能就剩下接受参数的类型吧,mixins接受的是数组.ide
new Vue({ extends: baseOptions, created(){ //do something console.log('onCreated-2'); } //其余自定义逻辑 }); // -> onCreated-1 // -> onCreated-2
从结果上看,三种方式都能实现需求,可是形式却有不一样.函数
Vue.extend
Vue.extend只是建立一个构造器,他是为了建立可复用的组件.
mixins,extends
而mixins和extends是为了拓展组件.
从源码来看经过extend,extends和mixins三种方式接收的options,最终都是经过mergeOptions进行合并的.差别只是官方文档中提到的优先级不一样extend > extends > mixins. 因此,若是是简单的扩展组件功能,三个方式均可以达到目的.
而这三种方式使用场景上细化的区分,目前我也蒙圈中...
//几种方式的不一样示例:
https://jsfiddle.net/willnewi...
上面提到的选项对象,是在mergeOptions中按照必定策略进行合并的.
打印Vue.config.optionMergeStrategies,你会看默认的optionMergeStrategies以下:
mergeHook
子组件和父组件的生命周期事件会合并在一个数组里。父组件在前,子组件在后。
watch
子组件和父组件的watchers会合并在一个数组里。父组件在前,子组件在后。
mergeAssets(filters,components,directives)
首先会在子组件里查找,若是没有,才会沿着原型链向上,找父组件中对应的属性。
data 合并规则
无重复的属性保留
同名覆盖
data中的对象也是相同规则,无重复的属性保留,同名覆盖
props、methods、computed: 无重复保留,同名子组件覆盖父组件
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 为了扩展
若是按照优先级去理解,当你须要继承一个组件时,可使用Vue.extend().当你须要扩展组件功能的时候,可使用extends,mixins.但目前为止尚未碰到完美诠释他们的场景,抱歉,能力有限?
href 属性用于保持光标形状为正常的手形,也可使用 css 实现
<a href="javascript:void(0);" @click="currentView = 'home'">
FOUC Flash Of Unstyled Content 文档样式闪烁