Vue中无关联上下文组件共享模板与逻辑的优选实现方案是什么
Vue无关联组件重叠逻辑/模板的最优实现方案
核心思路是关注点分离,完全抛弃组件继承方案,将公共逻辑、公共模板片段分别抽为独立的无业务绑定的复用单元,两个业务组件按需引入即可,全程保持各自上下文独立,无需感知对方的业务字段。
具体实现步骤
1. 抽取公共逻辑Mixin
将两个组件共同的count状态、基础add逻辑抽为单独的Mixin,无任何业务绑定,可被任意组件引入:
// base-count-mixin.js export default { data() { return { count: 0 } }, methods: { add() { this.count++ } } }
2. 抽取公共基础模板组件
将两个组件共同的<p>{{name}}</p>展示逻辑抽为纯展示组件,仅接收name属性,无任何额外业务逻辑:
// base-name-tag.js import Vue from 'vue' import Component from 'vue-class-component' @Component export default class BaseNameTag extends Vue { props: { name: String }, template: '<p>{{name}}</p>' }
3. 改造Pick组件
引入公共单元,仅保留Pick自身的业务逻辑:
// pick.js import Vue from 'vue' import Component from 'vue-class-component' import BaseCountMixin from './base-count-mixin' import BaseNameTag from './base-name-tag' @Component({ mixins: [BaseCountMixin], components: { BaseNameTag } }) export default class Pick extends Vue { template: '<base-name-tag :name="name" />', created() { console.log('Hello Pick'); } data: { name: 'pick' } }
4. 改造Drop组件
引入公共单元,自行覆盖/扩展自身独有的业务逻辑,全程不需要修改任何公共单元、Pick组件的代码:
// drop.js import Vue from 'vue' import Component from 'vue-class-component' import BaseCountMixin from './base-count-mixin' import BaseNameTag from './base-name-tag' @Component({ mixins: [BaseCountMixin], components: { BaseNameTag } }) export default class Drop extends Vue { template: ` <base-name-tag :name="name" /> <span v-if="isUserFriendly">Greetings!!!</span> `, created() { console.log('Hello Drop'); } data: { name: 'drop', isUserFriendly: false, drops: 0 }, methods: { // 自行覆盖公共add方法,不影响其他引入Mixin的组件 add: function () { this.count++; this.drops++; }, remove: function () { this.count--; }, } }
方案优势
- 两个业务组件完全解耦,上下文独立,无需感知对方的任何字段
- 公共逻辑、公共模板仅需维护一份,迭代修改时不会出现多份代码同步更新的问题
- 扩展成本低,后续新增同类组件仅需引入公共单元,添加自身业务逻辑即可
- 若后续升级到Vue3,可直接将Mixin替换为组合式API,复用逻辑的拆分粒度会更灵活,也能避免Mixin的命名冲突问题
内容的提问来源于stack exchange,提问作者Ron Yaari
相关产品推荐
相关产品推荐

