是否有可能在Vue.Js中传递计算属性中的参数。我可以看到,当有getter /setter使用computed时,他们可以接受一个参数并将其分配给一个变量。比如这里的文档:

computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
  
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

这也是可能的吗:

computed: {
  fullName: function (salut) {
    return salut + ' ' + this.firstName + ' ' + this.lastName    
  }
}

其中computed属性接受一个参数并返回所需的输出。然而,当我尝试这样做时,我得到这个错误:

vue.common.js:2250 Uncaught TypeError: fullName不是函数(…)

我是否应该在这种情况下使用方法?


当前回答

你需要小心vue/no-side-effects-in-computed-properties ESlint规则,不要在computed内部做任何事情。

与此同时,如果您正在寻找一种记忆方法,您可以阅读这篇文章或使用veuse的ememoize。

或者甚至从Vue3.2开始的v-memo。

其他回答

从技术上讲,我们可以将参数传递给计算函数,就像我们可以在vuex中将参数传递给getter函数一样。这样的函数是返回另一个函数的函数。

例如,在存储的getter中:

{
  itemById: function(state) {
    return (id) => state.itemPool[id];
  }
}

这个getter可以映射到组件的计算函数:

computed: {
  ...mapGetters([
    'ids',
    'itemById'
  ])
}

我们可以在模板中使用这个计算函数,如下所示:

<div v-for="id in ids" :key="id">{{itemById(id).description}}</div>

我们可以应用相同的方法来创建一个接受参数的计算方法。

computed: {
  ...mapGetters([
    'ids',
    'itemById'
  ]),
  descriptionById: function() {
    return (id) => this.itemById(id).description;
  }
}

并在模板中使用它:

<div v-for="id in ids" :key="id">{{descriptionById(id)}}</div>

话虽如此,我并不是说这是Vue的正确方式。

但是,我可以观察到,当具有指定ID的项在存储中发生变化时,视图确实会使用该项的新属性自动刷新其内容(绑定似乎工作得很好)。

我没有看到Vue3和/或使用组合API的答案,所以这里是我的位(,因为我总是忘记如何做到这一点)。

你可以通过将computed包装在另一个函数中来让它接受参数,就像这样:

const firstName = ref("John");
const lastName = ref("Doe");

const fullName = (salut: string) =>
  computed(() =>
    `${salut} ${firstName.value} ${lastName.value}`);

如果你想使用Pinia(传递参数给getter)进行状态管理,你可以使用这个计算getter:

// In component's setup function

const store = useStore();
const fullName = store.fullName("Hello"); // ComputedRef<string> 
console.log(fullName) // "Hello John Doe"

最可能的情况是使用方法

<span>{{ fullName('Hi') }}</span>

methods: {
  fullName(salut) {
      return `${salut} ${this.firstName} ${this.lastName}`
  }
}

更详细的解释

从技术上讲,你可以像这样使用一个带有参数的computed属性:

computed: {
   fullName() {
      return salut => `${salut} ${this.firstName} ${this.lastName}`
   }
}

(感谢Unirgy提供的基本代码。)

计算属性和方法之间的区别在于,计算属性是缓存的,仅当它们的依赖关系发生变化时才会更改。方法将在每次调用时求值。

如果需要参数,在这种情况下使用计算属性函数通常比使用方法没有任何好处。尽管它允许您将参数化getter函数绑定到Vue实例,但您将失去缓存,因此实际上没有任何增益,实际上,您可能会破坏反应性(AFAIU)。您可以在Vue文档https://v2.vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods中阅读更多相关内容

唯一有用的情况是当您必须使用getter并需要将其参数化时。例如,这种情况发生在Vuex中。在Vuex中,这是从存储中同步获取参数化结果的唯一方法(操作是异步的)。因此,官方Vuex文档列出了这种方法的getter https://vuex.vuejs.org/guide/getters.html#method-style-access

你需要小心vue/no-side-effects-in-computed-properties ESlint规则,不要在computed内部做任何事情。

与此同时,如果您正在寻找一种记忆方法,您可以阅读这篇文章或使用veuse的ememoize。

或者甚至从Vue3.2开始的v-memo。

您可以使用方法,但我仍然倾向于使用计算属性而不是方法,如果它们不会改变数据或没有外部影响的话。

你可以通过这种方式将参数传递给计算属性(没有文档,但由维护者建议,不记得在哪里):

computed: {
   fullName: function () {
      var vm = this;
      return function (salut) {
          return salut + ' ' + vm.firstName + ' ' + vm.lastName;  
      };
   }
}

编辑:请不要使用此解决方案,它只会使代码复杂化,没有任何好处。