Vue.js 列表渲染差异:"same object" vs "has same values"

Vue.js list rendering diff: "same object" vs "has same values"

我刚刚在 Vue.js (2.6.12) 组件中遇到了反应性问题。更新 props 后,它没有重新计算和重新渲染。问题是该组件在 v-forkey 的列表中使用。 key 没有改变,但对象的数据在改变,即它是同一个对象,但它的数据不同。

key 用于在 v-for 中区分列表的优化,因此它可以重新使用和重新排序相同的组件而无需重新创建它们。我原来的 key 是对象的 id,解决方案是根据 id 和所有对象的更改数据创建 key。这会导致其他问题,例如丢失组件的内部数据状态,而无需将其存储在 Vuex 存储中。

我的问题是,在 Vue.js 中(也许在 v3 中?)有没有办法告诉 v-for 对象是否相同(通过 key 使用对象的id) 但如果对象具有相同的数据呢?哪个将更新 prop 并重新计算和重新渲染组件而不丢失其内部数据?

有趣的是,组件的道具正在更新,它只是不重新计算和重新渲染。通过浏览器中的 Vue Devtools 验证。

编辑:

Here is an example 反应性不起作用的地方。它使用 Vuex 存储,v-for 的数组是计算的 属性,它连接了存储中的两个属性。

我刚刚发现问题是通过 67: o.number = extras[o.id] 行的 map 连接值。将其替换为 Vue.set(o, 'number', extras[o.id]) 后,它正在工作!

描述的不存在该问题。这是对象反应性正常工作的一个小例子:https://jsfiddle.net/sh0ber/04s1jt8g

不过,我猜您遇到了 change detection caveat 并且需要使用 Vue.set.

代码示例现在清楚了原因:您的计算在每个 Vuex obj 上创建了一个新的 属性 (number),您设置时未在 Vuex 中定义objs。如果您已将 objs 初始化为也有 number 属性,则您将不需要 Vue.set。证明它的另一种方法是设置 o.text 而不是 o.number 并且您会看到它在没有 Vue.set

的情况下是反应性的

(顺便说一句,在 Vuex getter 而不是计算中进行此计算更有意义;getter 是 Vuex 的计算。将逻辑与组件解耦很好,并假设您需要多个组件的结果)