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 的 Map
和 Set
数据类型旨在与它们的内置 get
/set
方法一起使用,我如何让 Vue 跟踪对内部状态的调用(以及更改) Map
s 和 Set
s 的?
【问题讨论】:
【参考方案1】:Vue.js 不支持对 Map
和 Set
数据类型的反应性(还没有?)。
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 值的反应版本,例如Map
或 Set
。
有一个问题。如果在自己的 JavaScript 中使用 Reference
,则需要添加 .value
以取消引用该值。在模板 html 中使用它不需要添加。这使得Reference
非常适合面向 UI 的事物,但对于内部编程则不那么适合。
我目前将Ref
后缀添加到提供Reference
的任何值或函数的名称中。这就是我。如果同时使用 Reference
和 Reactive
很容易混淆(TypeScript 会有所帮助)。
反应性
Reactive
用于类似地图的用途。可以将其初始化为:
const rve = reactive( new Map() )
访问此类不需要.value
。但是,Reactive
似乎没有允许它像 Map 一样使用的枚举方法(例如 .entries()
)。因此,它似乎针对的是您知道对象键的用例。但这可能会改变。
我希望 Reactive
能够被用作 ES Map
的 1:1 替代品。这对我来说很容易:Reactive
用于Map
s,Reference
用于其余部分。
我也希望名字能改变,让他们更亲近。 RMap
会很好 - 也许我会做一个(从 Reactive
派生并添加枚举方法)。
总结
对于 Vue 3,强烈的回答是“是”。
但是,开发人员指南可以更直接,清楚地说明选择Reference
或Reactive
的逻辑,以及例如什么。它们的运行时优缺点是,无需阅读各种博客文章。
编辑:我目前倾向于Ref
,但我尝试在代码中很早就解开反应性,导致computed
中只有一个.value
。
【讨论】:
对于绿色堆栈较少的每个人:在 Vue 2 中没有解决方法的情况下不支持以上是关于Vue 是不是支持 Map 和 Set 数据类型的反应性?的主要内容,如果未能解决你的问题,请参考以下文章