【发布时间】:2017-12-15 18:26:40
【问题描述】:
我有一个问题是 Vue 在更新响应式内容时反应迟缓。
我希望用户从列表中选择项目。当项目被选中时,它们应该被标记。对于测试,我只是在所选项目周围设置边框。问题是当我有多个项目时,我觉得Vue需要很长时间才能更新(反应)所选项目的类。
所以我有一个简单的响应式存储,如下所示:
export default new Vuex.Store({
state: {
selections: []
},
mutations: {
set_selections (state, sel) {
state.selections = sel;
}
}
})
我将此商店传递给我的组件,该组件会呈现一个包含许多项目的简单列表。
<p v-for="item in items">
<span v-bind:class="{ 'is-selected': isSelected(item) }" v-on:click="onSelect(item)">
{{ item.name }}
</span>
</p>
所以每个项目都有一个唯一的 id,我从我的 Vuex 商店状态中添加/删除,选择:
onSelect: function(item, event){
let itemId = item._id;
let sel = this.selections;
if (sel.indexOf(itemId) !== -1) {
var index = sel.indexOf(itemId);
sel.splice(index, 1);
} else {
sel.push(itemId);
}
this.$store.commit("set_selections", sel);
},
在哪里,
selections: function() {
return this.$store.state.selections;
}
是获取当前选择的计算属性。
检查项目是否被选中并因此将“is-selected”类添加到 DOM 元素的方法如下所示:
isSelected: function(item){
let itemId = item._id;
let sel = this.selections;
if (sel.indexOf(itemId) !== -1) {
return true;
}
return false;
},
问题
当我的列表中有很多项目时,我觉得反应性内容非常缓慢。当我单击一个项目时,大约需要 500 毫秒到 1 秒才能标记该项目。 (注意我有很多项目)。是,我可能做错了什么?由于我循环使用 v-for,我知道 Vue 必须为每个可能耗时的项目重新计算 isSelected 方法。
当然,我可以直接在 onClick 事件上添加/删除类,但是我失去了使用 Vue 的全部意义。你会如何处理这个问题?
【问题讨论】:
-
这几乎总是通过将列表项重构为一个组件来解决,这样 Vue 就不必重绘整个列表。
-
但是你会怎么做呢?我仍然需要遍历每个项目才能呈现它们?如果“isSelected”是在组件中计算出来的,它仍然会在更新时对每个项目调用“isSelected”。
-
当然,但只有更改的组件需要重绘。并非列表中的所有内容。用小提琴/笔将一个工作示例放在一起,我们可以进行重构。
-
确保将
key添加到您正在使用v-for的元素中。这可能会解决问题。 -
谢谢。我会试试的。那么如果我不把每个项目都放在一个组件中呢? Vue 居然重新渲染了整个列表?