Vue.js的文档提到了普通Javascript对象的智能自动更改跟踪:
当您将纯JavaScript对象作为其数据选项传递给Vue实例时,Vue.js将遍历其所有属性并使用Object.defineProperty将它们转换为getter / setter。
由于Javascript的Map
和Set
数据类型旨在与其内置get
/ set
方法一起使用,因此如何让Vue跟踪调用(以及因此,改变了Map
s和Set
s?
答案 0 :(得分:22)
Vue.js不支持对Map
和Set
数据类型的反应(但是?)。
feature ticket有一些讨论和解决方法(由用户" inca"):
Vue无法观察到集合和地图。为了使用那些 - 在
v-for
中,或在计算属性,方法,观察者, 模板表达式等 - 您需要创建一个可序列化的副本 这个结构并将其暴露给Vue。这是一个天真的例子 使用一个简单的计数器为Vue提供Set
的信息 更新:data() { mySetChangeTracker: 1, mySet: new Set(), }, computed: { mySetAsList() { // By using `mySetChangeTracker` we tell Vue that this property depends on it, // so it gets re-evaluated whenever `mySetChangeTracker` changes return this.mySetChangeTracker && Array.from(this.mySet); }, }, methods: { add(item) { this.mySet.add(item); // Trigger Vue updates this.mySetChangeTracker += 1; } }
这说明了一种有点hacky但100%有效的制作方法 不可观察的数据反应。在现实世界的情况下,我最终还是结束了 使用集合/地图的序列化版本(例如,您可能想要 将集合/映射的修改版本存储在localstorage中,从而 无论如何序列化它们,所以没有涉及人工计数器/黑客。
答案 1 :(得分:7)
是的。
Vue 3文档涵盖了Reactivity in depth和Basic Reactivity APIs。
另外还有“反应性”和“参考”四种。在使用Vue 3和ES6编码6个月以上之后,我仍在尝试寻找适合自己的使用模式。主要问题是使用Reactive
还是Reference
。
Reference
是简单的方法。例如,computed
返回的就是这个。它是一个人的JavaScript值的反应式版本,例如Map
或Set
。
有一个陷阱。如果一个人在自己的JavaScript中使用Reference
,则需要添加一个.value
来取消对该值的引用。在模板HTML中使用它不需要添加。这使Reference
非常适合面向UI的事物,而对于内部编程则不那么理想。
我目前将Ref
后缀添加到提供Reference
的任何值或函数的名称中。这就是我。如果同时使用Reference
和Reactive
很容易感到困惑(这里有TypeScript会有所帮助)。
Reactive
用于类似Map的用途。可以将其初始化为:
const rve = reactive( new Map() )
访问此类不需要.value
。但是,似乎Reactive
没有枚举方法(例如.entries()
)可以像Map一样使用。因此,它似乎针对您知道对象键的用例。但这可能会改变。
我希望Reactive
的发展方向是可以以1:1替代ES Map
。这对我来说很容易:Reactive
用于Map
,其余Reference
。
我也希望名称可以更改,以使它们更接近。 RMap
很好-也许我会做一个(从Reactive
派生并添加枚举方法)。
对于Vue 3,最有力的答案是“是”。
但是,开发人员指南可以变得更加简单明了,明确指出选择Reference
或Reactive
的逻辑是什么,例如。它们的运行时优缺点,而无需阅读各种博客文章。
编辑:我目前的倾向是Ref
,但我试图在代码中尽早展开反应性,导致.value
中只有一个computed
。
答案 2 :(得分:1)
据我所知,Vue的反应性跟踪分配。如果您在集合上执行分配,则它应该跟踪反应性,例如:
methods: {
add(item) {
this.mySet = new Set(this.mySet.add(item));
}
}
这为您提供了更简洁的代码,但存在一个明显的问题:性能。
只需根据需要选择解决方案即可:)