参考文章,请好好看这三篇,请好好看这三篇,请好好看这三篇
https://www.jb51.net/article/131008.htm
https://segmentfault.com/a/1190000010095089
https://segmentfault.com/a/1190000007087912#articleHeader4
mixins和extends都可以理解为继承
- mixins接收对象数组(可理解为多继承)
- extends接收的是对象或函数(可理解为单继承)
/*继承钩子函数*/
const extend = {
created () {console.log('extends created')}
}
const mixin1 = {
created () {console.log('mixin1 created')}
}
const mixin2 = {
created () { console.log('mixin2 created')}
}
export default {
extends: extend,
mixins: [mixin1, mixin2],
name: 'app',
created () {
console.log('created')
}
}
输出结果
extends created
mixin1 created
mixin2 created
created
结论:
- 继承钩子函数时,是不进行覆盖的,优先调用mixins和extends的钩子函数,extends触发的优先级更高
/*继承methods*/
const extend = {
data () {
return {name: 'extend name'}
}
}
const mixin1 = {
data () {
return { name: 'mixin1 name'}
}
}
const mixin2 = {
data () {
return {name: 'mixin2 name'}
}
}
// name = 'name'
export default {
mixins: [mixin1, mixin2],
extends: extend,
name: 'app',
data () {
return {
name: 'name'
}
}
}
//name = 'mixin2 name',extends优先级高会被mixins覆盖
export default {
mixins: [mixin1, mixin2],
extends: extend,
name: 'app'
}
//name = 'mixin1 name',mixins后面继承会覆盖前面的
export default {
mixins: [mixin2, mixin1],
extends: extend,
name: 'app'
}
结果
- 子类再次声明,data中的变量都会被重写,以子类的为准。
- 如果子类不声明,data中的变量将会最后继承的父类为准。
- 经过测试, props中属性 、 methods中的方法 和 computed的值 继承规则一样。
mixins
- 调用方式: mixins: [mixin1, mixin2]
- 是对组件的扩充,包括methods、components、directive等。。。
- 触发钩子函数时,先调用mixins的函数,再调用组件自身的函数。
- 虽然也能在创建mixin时添加data、template属性,但当组件自身也拥有此属性时以自己为准,从这一点也能看出制作者的用心(扩充)。
- data、methods内函数、components和directives等键值对格式的对象均以组件自身/实例为准
- mixin有自己的合并规则,如果你想修改默认规则,如想要修改 watch的合并策略
请看这篇:https://segmentfault.com/a/1190000007087912#articleHeader4
Vue.config.optionMergeStrategies.watch = function (toVal, fromVal) {
// return mergedVal
}
extends
- 调用方式: extends: CompA 同样是对组件的扩充,与mixins类似,但优先级均次于组件自身
extend
let options = {
template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
},
created(){
console.log('onCreated-1');
}
};
let BaseComponent = Vue.extend(options);
//基于基础组件BaseComponent,再扩展新逻辑.
new BaseComponent({
created(){
console.log('onCreated-2');
}
});
// -> onCreated-1
// -> onCreated-2
- Vue.extend 返回的是一个“扩展实例构造器”,预定义选项创建可复用的组件构造器
- 当我们调用vue.component(‘a’, {…})时自动调用
- 值得注意的是extend内的data为一个函数
结论:
- Vue.extend只是创建一个构造器,他是为了创建可复用的组件
- mixins和extends是为了拓展组件.
- 从源码来看通过extend,extends和mixins三种方式接收的options,最终都是通过mergeOptions进行合并的.差异只是官方文档中提到的优先级不同
extend > extends > mixins
component
/*Vue.component 是用来注册或获取全局组件的方法,其作用是将通过 Vue.extend
生成的扩展实例构造器注册为一个组件.*/
Vue.component('global-component', Vue.extend(baseOptions));
//传入一个选项对象(自动调用 Vue.extend),等价于上行代码.
Vue.component('global-component', baseOptions);
// 获取注册的组件(始终返回构造器)
var MyComponent = Vue.component('my-component')