Vue.js 使用共享方法/道具扩展传递给Vue组件的数据对象

Vue.js 使用共享方法/道具扩展传递给Vue组件的数据对象,vue.js,Vue.js,这是我的第一个Vue问题,因为我还在学习 假设我有一个组件: Vue.component('list-card', { props: ['entry'], computed: { isArchived: function() { return this.entry.Status == 'Archived' } }, template: `<div class="card"> <span clas

这是我的第一个Vue问题,因为我还在学习

假设我有一个组件:

Vue.component('list-card', {
    props: ['entry'],
    computed: {
        isArchived: function() { return this.entry.Status == 'Archived' }
    },
    template: `<div class="card">
        <span class="icon" :style="{ opacity: isArchived ? 0.2 : 1 }"></span>
    </div>`
});
Vue.component('list-card'{
道具:['entry'],
计算:{
isArchived:function(){返回this.entry.Status=='Archived'}
},
模板:`
`
});
现在,我想将该方法提取为ARCHIVED,因为我可能有其他类似的组件来渲染该卡-网格卡、板卡等。。。他们都需要isArchived,它不在entry对象中

对我来说,问题在于传递给组件的条目对象是一个POJO-plain数据对象,没有方法或计算属性。所以我必须定义组件本身的属性,而不是数据对象。根据我的OOP经验,这是错误的-entry.IsArchived()或entry.IsArchived prop更有意义

现在,我可以在将entry对象传递给组件之前,或者甚至在某些存储中获取条目时,等等,扩展这个对象,但我不想这样做-1。只有组件应该知道它们是否需要存档,以及2。这会影响性能-组件可能决定不使用isArchived,但我已经计算过了

那么,VueJS解决这个问题的正确方法是什么呢?

如前所述,
混合是为Vue组件分发可重用功能的一种灵活方法,因此您可以使用

//定义一个mixin对象
var myMixin={
道具:['entry'],
计算:{
isArchived:function(){返回this.entry.Status=='Archived'}
},
}
//定义使用此mixin的组件
var Component=Vue.extend({
mixin:[myMixin],
模板:`
`
})
var component=new component()//=>“你好,来自mixin!”

我建议尽量避免在重用组件中添加太多与项目业务相关的逻辑。例如,您可以提供布尔类型的
isArchived
属性,并且仅当父组件使用与我的两个观点相反的子组件时,才传入与
isArchived
相关的逻辑:1。父组件不应关心卡UI是否根据存档状态(或任何其他道具)发生更改2。父组件不应该预先计算isArchived prop,因为它甚至可能不被子组件使用-父组件不应该知道子组件的渲染细节。因此,为子组件预先计算道具不仅意味着更多的样板代码,而且意味着更紧密的耦合。例如,如果孩子决定更改其呈现方式,我们将不得不更改所有使用它的家长。找到了相同功能的请求:基本上,就像将入口对象接口提取到mixin中一样-类似于部分C#类?那么,什么是不同的组件具有不同的条目名称-例如,一个使用“条目”而另一个使用“卡片”?不管怎样,我阅读了文档,我看到我可以将道具(条目)名称传递给mixin。因此,这看起来是一个很好的解决方案,但我犹豫有两个原因:1。我看到它被认为是反模式的,例如,见2。出于这个原因,我不确定mixin是否真的是“正确的Vue方式”。假设我有一个组件,它传递了两个条目-oldCard和newCard。我可以将这些名称传递给添加到组件中的两个mixin,但mixin的计算属性对于这两个卡对象将始终是归档的-据我所知。所以Vue3用合成API解决了这个问题,但我想知道Vue2中是否有更好的方法。正如您所说,Vue3中的合成API是更好的方法。但在Vue2中,方式是混合
// define a mixin object
var myMixin = {
   props: ['entry'],
    computed: {
        isArchived: function() { return this.entry.Status == 'Archived' }
   },
}

// define a component that uses this mixin
var Component = Vue.extend({
  mixins: [myMixin],
  template: `<div class="card">
        <span class="icon" :style="{ opacity: isArchived ? 0.2 : 1 }"></span>
    </div>`
})

var component = new Component() // => "hello from mixin!"