【问题标题】:Does Vue support reactivity on Map and Set data types?Vue 是否支持 Map 和 Set 数据类型的反应性?
【发布时间】:2023-03-27 18:44:01
【问题描述】:

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

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

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

【问题讨论】:

    标签: vue.js


    【解决方案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 depthBasic 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 中没有解决方法的情况下不支持
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      相关资源
      最近更新 更多