Vue2环境下vue-class-component库:extends继承父组件与mixins混入父组件的子组件是否等价?
回答:extends Parent vs mixins(Parent) 在 vue-class-component 中的差异
先直接给结论:这两种写法在基础功能表现上(比如访问父组件的属性、钩子执行顺序)看起来相似,但生成的子组件并不是完全一致的,底层实现和一些细节行为存在差异。下面具体拆解:
1. 原型链结构的本质区别
ChildOne extends Parent是基于ES6的类继承机制,所以ChildOne的原型链是:ChildOne → Parent → Vue → Object。这意味着ChildOne的实例同时也是Parent的实例(new ChildOne() instanceof Parent返回true),你可以在ChildOne中通过super直接调用Parent的方法(比如super.created())。ChildTwo extends mixins(Parent)是利用Vue的mixin机制,mixins(Parent)会把Parent的组件选项(由vue-class-component从class转化而来)合并到ChildTwo的选项中。此时ChildTwo的原型直接指向Vue,和Parent没有原型链关联(new ChildTwo() instanceof Parent返回false),也无法通过super调用Parent的方法。
2. 组件选项合并的优先级差异
Vue本身对extends和mixins的选项合并有优先级区分:
- 当使用
extends Parent时,Parent的选项会被当作"父级选项",优先级低于ChildOne自身的选项,但高于普通mixin。 - 当使用
mixins(Parent)时,Parent的选项会被当作普通mixin处理,优先级低于ChildTwo自身的选项,同时如果有多个mixin,后面的mixin优先级高于前面的。
不过在你的示例代码中,因为只有单个父组件/mixin,这部分的差异不会体现出来,但如果后续扩展多个mixin或者同名选项,差异就会显现。
3. 实际功能表现的细微差异
在你的示例中,两个子组件都能正常访问this.p并在created中打印,这是因为vue-class-component会把class的实例属性转化为组件的data选项,无论是继承还是mixin都会合并这些属性。但如果涉及到方法调用、实例判断等场景,差异就会出现:
- 比如在
ChildOne中可以用super调用Parent的方法,ChildTwo不行; - 比如判断实例归属时,
ChildOne的实例属于Parent的实例范畴,ChildTwo不属于。
总结来说,虽然基础功能表现一致,但两者的底层实现机制和原型链结构完全不同,生成的子组件并不是完全等价的。如果你的场景只需要复用属性和钩子,两种写法都能工作,但如果需要基于原型链的继承特性(比如super调用、实例判断),就必须使用extends语法。
内容的提问来源于stack exchange,提问作者Markus Weninger
相关产品推荐
相关产品推荐

