Vue.js列表呈现差异:“相同的对象”与“具有相同的值”

问题描述

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

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

我的问题是,在Vue.js中(也许在v3中吗?)是否可以在v-for中告诉对象是否相同(通过使用对象ID的key),也可以对象是否具有相同的数据?哪个会更新道具,重新计算并重新渲染组件而又不会丢失其内部数据?

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

编辑:

Here is an example,其中反应性不起作用。它正在使用Vuex商店,v-for的数组是一个计算属性,该属性将商店中的两个属性结合在一起。

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

解决方法

该问题不存在,如上所述。这是对象反应正常运行的一个小示例:https://jsfiddle.net/sh0ber/04s1jt8g

但是,我猜测您遇到change detection caveat,需要使用namespace ns { template<const char* str> struct Foo { }; char name[] = "Test"; // Adding either "static" or "const" causes C2970 Foo<name> foo; } int main() { }

现在通过代码示例可以清楚地说明原因:您的计算值会在设置Vue.set时未在Vuex中定义的每个Vuex number上创建一个新属性(obj)。如果您还初始化了objs以使其具有objs属性,则不需要number。证明它的另一种方法是设置Vue.set而不是o.text,您会发现它在没有o.number的情况下是无功的

(顺便说一句,在Vuex getter中进行此计算而不是在计算中更有意义; getter是为Vuex计算的。将逻辑与组件分离,并想象您需要多个组件中的结果是很好的) / p>