Can I pass parameters in computed properties in Vue.Js
这有可能在Vue.Js中的计算属性中传递参数。 我可以看到在使用getters / setter进行计算时,他们可以采用参数并将其分配给变量。 就像这里的文档:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // ... 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] } } } // ... |
这也是可能的:
1 2 3 4 5 6 7 | // ... computed: { fullName: function (salut) { return salut + ' ' + this.firstName + ' ' + this.lastName } } // ... |
其中,calculated属性接受一个参数并返回所需的输出。 但是,当我尝试此操作时,出现此错误:
vue.common.js:2250 Uncaught TypeError: fullName is not a function(…)
我应该在这种情况下使用方法吗?
您最有可能想要使用一种方法
1 2 3 4 5 6 7 | <span>{{ fullName('Hi') }}</span> methods: { fullName(salut) { return `${salut} ${this.firstName} ${this.lastName}` } } |
更长的解释
从技术上讲,您可以将计算属性与如下参数一起使用:
1 2 3 4 5 | computed: { fullName() { return salut => `${salut} ${this.firstName} ${this.lastName}` } } |
(为此感谢
计算属性和方法之间的区别在于,计算属性将被缓存并仅在其依赖项更改时更改。方法将在每次调用时进行评估。
如果需要参数,在这种情况下,使用计算属性函数比使用方法通常没有任何好处。尽管它使您可以将参数化的getter函数绑定到Vue实例,但是您会丢失缓存,因此实??际上并没有任何收获,实际上,您可能会破坏反应性(AFAIU)。您可以在Vue文档https://vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods中阅读有关此内容的更多信息。
唯一有用的情况是必须使用吸气剂并对其进行参数设置。这种情况例如发生在Vuex中。在Vuex中,这是从存储中同步获取参数化结果的唯一方法(动作是异步的)。因此,此方法已在Vuex官方文档中列出以获取其方法
https://vuex.vuejs.org/guide/getters.html#method-style-access
您可以使用方法,但是如果它们不变异数据或没有外部影响,我还是更喜欢使用计算属性而不是方法。
您可以通过这种方式将参数传递给计算属性(未记录,但由维护人员建议,不记得在哪里):
1 2 3 4 5 6 7 8 | computed: { fullName: function () { var vm = this; return function (salut) { return salut + ' ' + vm.firstName + ' ' + vm.lastName; }; } } |
编辑:请不要使用此解决方案,它只会使代码复杂,没有任何好处。
好吧,从技术上讲,我们可以将参数传递给计算函数,就像我们将参数传递给vuex中的getter函数一样。这样的函数是返回函数的函数。
例如,在商店的吸气剂中:
1 2 3 4 5 | { itemById: function(state) { return (id) => state.itemPool[id]; } } |
该getter可以映射到组件的计算函数:
1 2 3 4 5 6 | computed: { ...mapGetters([ 'ids', 'itemById' ]) } |
我们可以在模板中使用此计算函数,如下所示:
1 | {{itemById(id).description}} |
我们可以应用相同的方法来创建带有参数的计算方法。
1 2 3 4 5 6 7 8 9 | computed: { ...mapGetters([ 'ids', 'itemById' ]), descriptionById: function() { return (id) => this.itemById(id).description; } } |
并在我们的模板中使用它:
1 | {{descriptionById(id)}} |
话虽这么说,但我并不是说这是使用Vue做事的正确方法。
但是,我可以观察到在商店中对具有指定ID的商品进行了更改时,视图会使用该商品的新属性自动刷新其内容(绑定似乎工作得很好)。
过滤器是Vue组件提供的功能,可让您将格式设置和转换应用于模板动态数据的任何部分。
它们不会更改组件的数据或其他任何内容,而只会影响输出。
假设您正在打印名称:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | new Vue({ el: '#container', data() { return { name: 'Maria', lastname: 'Silva' } }, filters: { prepend: (name, lastname, prefix) => { return `${prefix} ${name} ${lastname}` } } }); |
1 2 3 4 5 | <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"> <p> {{ name, lastname | prepend('Hello') }}! </p> |
请注意应用过滤器的语法,即|。 filterName。如果您熟悉Unix,那就是Unix管道运算符,用于将操作的输出作为输入传递给下一个操作。
组件的滤镜属性是一个对象。
单个过滤器是一个接受一个值并返回另一个值的函数。
返回的值是Vue.js模板中实际打印的值。
您还可以通过返回函数将参数传递给getter。当您要查询存储中的数组时,这特别有用:
1 2 3 4 5 6 7 | getters: { // ... getTodoById: (state) => (id) => { return state.todos.find(todo => todo.id === id) } } store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false } |
请注意,通过方法访问的getter将在您每次调用它们时运行,并且结果不会被缓存。
这称为"方法样式访问",并记录在Vue.js文档中。
You can pass parameters but either it is not a vue.js way or the way you are doing is wrong.
但是在某些情况下需要这样做。我将向您展示一个简单的示例,该示例使用getter和setter将值传递给计算属性。
1 2 3 4 5 6 | <template> Your name is {{get_name}} <!-- John Doe at the beginning --> <button @click="name = 'Roland'">Change it</button> </template> |
和脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | export default { data: () => ({ name: 'John Doe' }), computed:{ get_name: { get () { return this.name }, set (new_name) { this.name = new_name } }, } } |
单击按钮时,我们将名称传递给计算属性" Roland",在
在下面的示例中,有一个常见的用例,即与getter和setter一起使用计算时。
假设您拥有以下vuex商店:
1 2 3 4 5 6 7 8 9 10 11 | export default new Vuex.Store({ state: { name: 'John Doe' }, getters: { get_name: state => state.name }, mutations: { set_name: (state, payload) => state.name = payload }, }) |
并且在您的组件中,您想使用vuex存储将
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <template> <input type="text" v-model="get_name"> {{get_name}} </template> export default { computed:{ get_name: { get () { return this.$store.getters.get_name }, set (new_name) { this.$store.commit('set_name', new_name) } }, } } |
计算可以考虑具有功能。因此,对于检定的一个例子,您可以明确地执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 | methods: { validation(attr){ switch(attr) { case 'email': const re = /^(([^<>()\\[\\]\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\.,;:\\s@\"]+)*)|(\".+\"))@(([^<>()[\\]\\.,;:\\s@\"]+\\.)+[^<>()[\\]\\.,;:\\s@\"]{2,})$/i; return re.test(this.form.email); case 'password': return this.form.password.length > 4 } }, ... } |
您将使用的类似:
1 2 3 4 5 6 7 8 | <b-form-input id="email" v-model="form.email" type="email" :state="validation('email')" required placeholder="Enter email" ></b-form-input> |
请记住,您仍然会错过特定于计算的缓存。
1 2 3 4 5 | computed: { fullName: (app)=> (salut)=> { return salut + ' ' + this.firstName + ' ' + this.lastName } } |
当你想使用
1 2 3 | <p> {{fullName('your salut')}} </p> |
我不确定您要实现的目标,但看起来使用方法而不是计算方法将完全可以!
是的,那里有使用参数的方法。像上面提到的答案一样,在您的示例中,最好使用方法,因为执行非常轻便。
仅供参考,在方法复杂且成本高的情况下,可以缓存结果,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | data() { return { fullNameCache:{} }; } methods: { fullName(salut) { if (!this.fullNameCache[salut]) { this.fullNameCache[salut] = salut + ' ' + this.firstName + ' ' + this.lastName; } return this.fullNameCache[salut]; } } |
注意:使用此功能时,如果要处理数千个内存,请注意内存