Vue 是不是支持 Map 和 Set 数据类型的反应性?

Posted

技术标签:

【中文标题】Vue 是不是支持 Map 和 Set 数据类型的反应性?【英文标题】:Does Vue support reactivity on Map and Set data types?Vue 是否支持 Map 和 Set 数据类型的反应性? 【发布时间】:2016-09-04 22:25:43 【问题描述】:

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

当您将纯 JavaScript 对象作为其数据选项传递给 Vue 实例时,Vue.js 将遍历其所有属性并使用 Object.defineProperty 将它们转换为 getter/setter。

由于 Javascript 的 MapSet 数据类型旨在与它们的内置 get/set 方法一起使用,我如何让 Vue 跟踪对内部状态的调用(以及更改) Maps 和 Sets 的?

【问题讨论】:

【参考方案1】:

Vue.js 不支持对 MapSet 数据类型的反应性(还没有?)。

feature ticket 有一些讨论和解决方法(由用户“inca”):

Sets 和 Maps 不能被 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% 的制作方法 不可观察的数据反应。尽管如此,在现实世界的案例中,我最终还是 使用 Sets/Maps 的序列化版本(例如,您可能想要 将 set/maps 的修改版本存储在 localstorage 中,因此 无论如何都要序列化它们),因此不涉及人工计数器/黑客。

【讨论】:

【参考方案2】:

据我所知,Vue 的反应性跟踪分配。如果你在你的集合上执行任务,它应该跟踪反应性,例如:

methods: 
  add(item) 
    this.mySet = new Set(this.mySet.add(item));
  

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

只需根据您的需要选择您的解决方案 :)

【讨论】:

内部非常好,谢谢 :) 我现在已将代码重构为 Array。但我徘徊:如果我需要删除 elem,那么性能更高。设置new Set(),还是在数组上创建.filter()【参考方案3】:

Vue 3

是的,确实如此。

Vue 3 文档在 Reactivity in depth 和 Basic Reactivity APIs 上介绍了这些内容。

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

参考

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

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

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

反应性

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

const rve = reactive( new Map() )

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

我希望 Reactive 能够被用作 ES Map 的 1:1 替代品。这对我来说很容易:Reactive 用于Maps,Reference 用于其余部分。

我也希望名字能改变,让他们更亲近。 RMap 会很好 - 也许我会做一个(从 Reactive 派生并添加枚举方法)。

总结

对于 Vue 3,强烈的回答是“是”。

但是,开发人员指南可以更直接,清楚地说明选择ReferenceReactive 的逻辑,以及例如什么。它们的运行时优缺点是,无需阅读各种博客文章。


编辑:我目前倾向于Ref,但我尝试在代码中很早就解开反应性,导致computed中只有一个.value

【讨论】:

对于绿色堆栈较少的每个人:在 Vue 2 中没有解决方法的情况下不支持

以上是关于Vue 是不是支持 Map 和 Set 数据类型的反应性?的主要内容,如果未能解决你的问题,请参考以下文章

JS中的数据类型,包含ES6,set和map等等

Map和Set

list、set、map 之间的区别是啥?

JavaScript-Map和Set

es6 map数据类型,要比set还很多

java中关于map值修改问你