VUE首选哪种共享模板和逻辑的方法?

Posted

技术标签:

【中文标题】VUE首选哪种共享模板和逻辑的方法?【英文标题】:Which approach of sharing template and logic is preferred in VUE? 【发布时间】:2021-12-10 18:30:35 【问题描述】:

我有两个不相关的上下文组件,它们共享逻辑和模板,看起来像是在扩展另一个。

想象一下这样的 Drop 和 Pick 组件:

// pick.js
import Vue from 'vue'
import Component from 'vue-class-component'

@Component
export default class Pick extends Vue 
  template: '<p>name</p>',
  created() 
    console.log('Hello Pick');
  
  data:  
    name: 'pick',
    count: 0
  ,
  methods: 
    add: function () 
      this.count++;
    
  


// drop.js
import Vue from 'vue'
import Component from 'vue-class-component'

@Component
export default class Drop extends Vue 
  template: '<p>name</p> <span v-if="isUserFriendly">Greetings!!!</span>',
  created() 
    console.log('Hello Drop');
  
  data:  
    name: 'drop',
    isUserFriendly: false,
    count: 0,
    drops: 0
  ,
  methods: 
    add: function () 
      this.count++;
      this.drops++;
    ,
    remove: function () 
      this.count--;
    ,
  

直观地说,Drop 在添加一些功能和更改模板的同时扩展了 Pick。这似乎是一个很好的解决方案,但后来我想,要实现 Pick 模板应该如下所示:

<p>name</p> 
<span v-if="isUserFriendly">Greetings!!!</span>

还记得我说过不相关的上下文组件吗? 现在 Pick 需要了解 isUserFriendly ,这是不可接受的,我也不认为它是正确的解决方案。此外,它会在未来产生开销,因为继承可能难以维护(想象更多要扩展的组件和要共享的逻辑)。

您认为这里最好的方法是什么?也许还有另一种我不熟悉的方法?

感谢您的帮助!

【问题讨论】:

【参考方案1】:

组件组合是执行此操作的常用方法。 Drop 组件包含一个超集功能,即,pick 组件应该允许以允许所需输出和行为的方式进行包装。

对于父子关系,数据块作为道具和事件传递,视图块作为槽传递。

附加逻辑保留在父组件中。

在子组件中(Pick):

<div>
  <p>name</p>
  <slot name="extraText"/>
</div>

add: function () 
  this.count++;
  this.$emit('add');

在父组件中(Drop):

<Pick @add="drops++">
  <template v-slot:extraText>
    <span>Greetings!!!</span>
  </template>
</Pick>

【讨论】:

我真的很喜欢这种方法!如果 add() 将完全不同,因为 DROP 包含 add() 的另一个实现,它与 Pick 实现无关。例如,我现在不想调用 this.count++ 那么可能子组件应该更简单的实现,Pick和Drop都会扩展它的功能。

以上是关于VUE首选哪种共享模板和逻辑的方法?的主要内容,如果未能解决你的问题,请参考以下文章

vue.js的条件渲染,其实就是模板里面写if else

SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 后端篇: 数据表设计使用 jwtredissms 工具类完善注册登录逻辑

Vue之计算属性

Vue2.0笔记——计算属性和侦听器

Vue源码中compiler部分逻辑梳理(内有彩蛋)

Vue计算属性和侦听器