关于vue.js:Vue是否支持Map和Set数据类型的反应性?

Does Vue support reactivity on Map and Set data types?

Vue.js的文档提到了针对普通Javascript对象的智能自动更改跟踪:

When you pass a plain JavaScript object to a Vue instance as its data option, Vue.js will walk through all of its properties and convert them to getter/setters using Object.defineProperty.

由于Javascript的MapSet数据类型被设计为与它们的内置get / Set方法一起使用,因此如何获得Vue来跟踪对( Map s和Set s的内部状态?


Vue.js不支持对MapSet数据类型的响应(还可以吗?)。

功能票进行了一些讨论,并且可以通过用户" inca "来解决:

Sets and Maps are not observable by Vue. In order to use those a€"
either in v-for, or in computed properties, methods, watchers,
template expressions, etc. a€" you need to create a serializable replica
of this structure and expose it to Vue. Here's a naive example which
uses a simple counter for providing Vue with information that Set is
updated:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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;
  }
}

This illustrates a kinda hacky but 100% working method for making
non-observable data reactive. Still, in real world cases I ended up
with serialized versions of Sets/Maps (e.g. you'd probably want to
store the modified versions of sets/maps in localstorage and thus
serialize them anyway), so no artificial counters/hacks were involved.


据我所知,Vue的反应性跟踪作业。如果您在集合上执行任务,则它应跟踪反应性,例如:

1
2
3
4
5
methods: {
  add(item) {
    this.mySet = new Set(this.mySet.add(item));
  }
}

这为您提供了更简洁的代码,但存在一个明显的问题:性能。

只需根据需要选择解决方案即可:)


Vue 3

是的。

Vue 3文档在"深度反应性"和"基本反应性API"中进行了介绍。

另外还有四种" reactive "和" reference "。在使用Vue 3和ES6编码6个月后,我仍在尝试寻找适合我的使用模式。主要问题是,是使用Reactive还是Reference

参考

Reference是简单的方法。例如,这就是computed返回的内容。它是一个人的JavaScript值的反应式版本,例如MapSet

有一个陷阱。如果一个人在自己的JavaScript中使用Reference,则需要添加一个.value以取消对该值的引用。在模板HTML中使用它不需要添加。这使得Reference非常适合面向UI的事物,但对于内部编程则不那么理想。

我目前将Ref后缀添加到提供Reference的任何值或函数的名称中。这就是我。如果同时使用ReferenceReactive,很容易感到困惑(TypeScript会有所帮助)。

反应性

Reactive用于类似Map的用途。可以将其初始化为:

1
const rve = reactive( new Map() )

访问此类不需要.value。但是,Reactive似乎没有允许将其像Map一样使用的枚举方法(例如.entries())。因此,它似乎针对的是您知道对象键的用例。但这可能会改变。

我希望Reactive的使用方向是可以将其作为ES Map的1:1替代品。这对我来说很容易:Reactive用于Map s,其余Reference

我也希望名称可以更改,以使它们更接近。 RMap会很好-也许我会做一个(从Reactive派生并添加枚举方法)。

概括

对于Vue 3,最有力的答案是"是"。

但是,开发人员指南可以变得更加简单明了,明确指出选择ReferenceReactive的逻辑是什么,例如。它们的运行时优缺点,而无需阅读各种博客文章。

编辑:我目前的倾向是Ref,但是我试图在代码中尽早解开反应性,导致在computed中只有一个.value