我通过遍历大量对象来生成Vue组件的内容。我想使用计算出的属性来确定是否显示某些节点,但是由于计算出的引用是在循环内使用的,因此我需要能够动态设置引用名称。
下面是我正在尝试做的一个概念性示例。如何根据当前项目更改showItemX
?
<template>
<ul>
<li v-for="item in myArr" v-if="showItemX">
{{ item.name }}
</li>
</ul>
</template>
<script>
export default {
data() {
return {
myArr: [{
id: 'item1',
name: 'Item 1'
}, {
id: 'item2',
name: 'Item 2'
}]
};
},
computed: {
showItem1: function() {
return this.$store.state.showItem1;
},
showItem2: function() {
return this.$store.state.showItem2;
}
}
}
</script>
到目前为止,这是我考虑过的两条路线,但是我不确定哪条路线会更有效,或者是否会首选另一种方式:
在此选项中,上面的两个计算的属性将合并为一个属性:
computed: {
showItem: function() {
return {
item1: this.$store.state.showItem1,
item2: this.$store.state.showItem2
}
}
}
然后将v-if
设置为showItem[item.id]
:
<li v-for="item in myArr" v-if="showItem[item.id]">
{{ item.name }}
</li>
这里的缺点是,每次依赖项之一更改时,整个对象似乎都会重新计算。
在这里,我尝试将item.id
传递给方法,以访问相应的计算属性:
computed: {
item1Show: function() {
return this.$store.state.showItem1;
},
item2Show: function() {
return this.$store.state.showItem2;
}
},
methods: {
showItem: function(id) {
return this[id + 'Show']
}
}
在模板中:
<li v-for="item in myArr" v-if="showItem(item.id)">
{{ item.name }}
</li>
同样,在此示例中,我不确定是否可以充分利用计算出的属性。
这些选项中的一个应该比另一个更受青睐吗?还是有更好的方法来实现我所缺少的呢?
答案 0 :(得分:0)
关于Vue和JavaScript的好处是,您可以使用任何适合您需要的方法,但是,首先,我可能会找到类似以下最容易理解的内容
<li v-for="item in myArr" v-if="showItem(item)">
{{ item.name }}
</li>
然后定义showItem
方法,例如
showItem(item) {
return item.id === "item1" ?
this.$store.state.showItem1 :
this.$store.state.showItem2;
}
假设您没有在帖子中未显示的其他地方使用计算所得的属性
答案 1 :(得分:0)
有更好的方法。
对于可能的解决方案#1,您最好也这样做
<li v-for="(item, index) in myArr" v-if="$store.state['showItem' + (index + 1)]">
可能的解决方案#2,您完全会错过Vue的优化。 该方法虽然不占用大量计算资源,但将为每个渲染器的每个元素重新运行。
以下是适合您示例问题的特定参数的解决方案。但是,这实际上不是我在这里推荐的。下面有更多内容。
<template>
<ul>
<!--
`:key` is crucial for performance.
otherwise, every element will re-render
whenever the filtered array updates.
-->
<li v-for="item in myFilteredArr" :key="item.id">
{{ item.name }}
</li>
</ul>
</template>
<script>
export default {
data: _ => ({
myArr: [
{
id: 'item1',
name: 'Item 1'
},
{
id: 'item2',
name: 'Item 2'
}
],
}),
computed: {
myFilteredArr () {
/*
abstracting state to a constant avoids
re-running the getter functions each iteration
*/
const state = this.$store.state;
return this.myArr.filter(
(item, index) => state['showItem' + (index + 1)]
);
}
}
}
</script>
我的实际建议是将所有这些逻辑转移到Vuex吸气剂中。您可以在这里阅读有关它们的信息:https://vuex.vuejs.org/guide/getters.html。
由于您的过滤逻辑已在商店中处理,因此可以将设置所有showItem
的函数剪切并粘贴到Vuex getter中,以相同的方式返回myFilteredArr
如上所述。
这样,就没有组件<->商店相互依赖,并且商店的状态将更加整洁。