我可以在 Vue.Js 的计算属性中传递参数吗

IT技术 javascript vue.js vuejs2
2021-01-23 05:40:41

这是否可以在 Vue.Js 中的计算属性中传递参数。我可以看到当使用计算的 getter/setter 时,他们可以获取一个参数并将其分配给一个变量。就像这里的文档

// ...
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    
  }
}
// ...

其中计算属性接受一个参数并返回所需的输出。但是,当我尝试此操作时,出现此错误:

vue.common.js:2250 Uncaught TypeError: fullName is not a function(...)

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

6个回答

很可能你想使用一种方法

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

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

更长的解释

从技术上讲,您可以使用具有如下参数的计算属性:

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

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

计算属性和方法之间的区别在于,计算属性会被缓存,并且只有在它们的依赖关系发生变化时才会发生变化。一个方法将评估每一个,它被称为时间

如果您需要参数,在这种情况下使用计算属性函数通常没有好处。尽管它允许您将参数化的 getter 函数绑定到 Vue 实例,但您会丢失缓存,因此实​​际上没有任何收益,实际上,您可能会破坏react性 (AFAIU)。您可以在 Vue 文档https://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列出了这种方法

非常彻底谢谢!
2021-04-05 05:40:41

您可以使用方法,但我更喜欢使用计算属性而不是方法,如果它们不会改变数据或没有外部影响。

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

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

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

我不相信它会在返回函数中缓存任何东西。与方法的区别纯粹是约定俗成的(方法有效果,计算仅用于检索)
2021-03-14 05:40:41
如果您可以提供参考,那将非常有帮助。这应该有效。
2021-03-24 05:40:41
这对我有用,但我唯一不喜欢的是它返回一个函数而不是实际属性,因此 VueJS 开发工具不会在任何地方显示结果。我不确定这对于计算属性是否是典型的,但它使故障排除有点困难。
2021-03-30 05:40:41
@saurabh 抱歉,这是 github 中一个非描述性问题的解决方案,我现在找不到它...
2021-04-01 05:40:41
它如何处理缓存?参数改变时会正常工作吗?
2021-04-04 05:40:41

好吧,从技术上讲,我们可以将参数传递给计算函数,就像我们可以将参数传递给 vuex 中的 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 的项目在商店中发生变异时,视图会使用该项目的新属性自动刷新其内容(绑定似乎工作得很好)。

@james.brndwgn 如果可能的话,我宁愿使用计算属性而不是观察者。我只是对您的陈述提出异议:“因此,使用此方法没有实际收益。” 因为即使没有缓存也有显着差异。
2021-03-15 05:40:41
@james.brndwgn 但我很确定当底层数据改变时方法不会重新运行。这就是我真正要寻找的。
2021-03-16 05:40:41
虽然这确实有效,但它本质上将计算属性视为方法。即它失去了计算属性的缓存优势。因此,在方法上使用它没有实际收益。“请注意,通过方法访问的 getter 将在您每次调用它们时运行,并且结果不会被缓存。” vuex.vuejs.org/en/getters.html
2021-03-22 05:40:41
哇所以这对我有用,而不是使用 vuex 。还想知道这是否是计算属性的合法方式。
2021-03-31 05:40:41
@Alex 那么你应该使用观察者。vuejs.org/v2/guide/computed.html#Watchers
2021-03-31 05:40:41

过滤器是 Vue 组件提供的一项功能,可让您将格式和转换应用于模板动态数据的任何部分。

它们不会更改组件的数据或任何内容,但只会影响输出。

假设你正在打印一个名字:

new Vue({
  el: '#container',
  data() {
    return {
      name: 'Maria',
      lastname: 'Silva'
    }
  },
  filters: {
    prepend: (name, lastname, prefix) => {
      return `${prefix} ${name} ${lastname}`
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="container">
  <p>{{ name, lastname | prepend('Hello') }}!</p>
</div>

注意应用过滤器的语法,即 | 过滤器名称。如果您熟悉 Unix,那就是 Unix 管道运算符,它用于将操作的输出作为输入传递给下一个操作。

组件的过滤器属性是一个对象。单个过滤器是一个接受一个值并返回另一个值的函数。

返回值是实际打印在 Vue.js 模板中的值。

您可以传递参数,但要么不是 vue.js 方式,要么是您的方式错误。

但是,有些情况下您需要这样做。我将向您展示一个使用 getter 和 setter 将值传递给计算属性的简单示例。

<template>
    <div>
        Your name is {{get_name}} <!-- John Doe at the beginning -->
        <button @click="name = 'Roland'">Change it</button>
    </div>
</template>

还有剧本

export default {
    data: () => ({
        name: 'John Doe'
    }),
    computed:{
        get_name: {
            get () {
                return this.name
            },
            set (new_name) {
                this.name = new_name
            }
        },
    }    
}

单击按钮时,我们将名称“Roland”传递给计算属性,set()并将名称从“John Doe”更改为“Roland”。

下面是一个常见的用例,当计算与 getter 和 setter 一起使用时。假设您有以下 vuex 商店:

export default new Vuex.Store({
  state: {
    name: 'John Doe'
  },
  getters: {
    get_name: state => state.name
  },
  mutations: {
    set_name: (state, payload) => state.name = payload
  },
})

在您的组件中,您想要添加v-model到输入但使用 vuex 存储。

<template>
    <div>
        <input type="text" v-model="get_name">
        {{get_name}}
    </div>
</template>
<script>
export default {
    computed:{
        get_name: {
            get () {
                return this.$store.getters.get_name
            },
            set (new_name) {
                this.$store.commit('set_name', new_name)
            }
        },
    }    
}
</script>