vue.js

Does Vue support reactivity on Map and Set data types?


The docs for Vue.js mention the smart auto-change-tracking for plain Javascript objects:

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.

Since Javascript's Map and Set datatypes are designed to be used with their in-built get/set methods, how can I get Vue to track calls (and therefore, changes) to the internal state of Maps and Sets?


Solution

  • Vue 3

    Yes, it does.

    Vue 3 docs cover these at Reactivity in depth and Basic Reactivity APIs.

    There are four kinds of "reactive" and the "reference" in addition. I'm still trying to find the usage patterns that suit me, after 6+ months with Vue 3 and ES6 coding. The main question is, whether to use Reactive or Reference.

    Reference

    Reference is the easy way to go. This is what gets returned by computed, for example. It makes a reactive version of one's JavaScript value, e.g. a Map or a Set.

    There's a gotcha. If one uses Reference in one's JavaScript, a .value needs to be added to dereference the value. Using it in template HTML does not need that addition. This makes Reference perfect for UI facing things, but less so for internal programming.

    I currently add Ref postfix to the name of any value or function that provides a Reference. That's just me. It's easy to get confused if one uses both Reference and Reactive (TypeScript would help, here).

    Reactive

    Reactive is made for Map-like use. One can initialise it as:

    const rve = reactive( new Map() )
    

    Accessing such does not need the .value. However, it seems Reactive does not have the enumeration methods (e.g. .entries()) that would allow it to be used Map-like. Therefore, it seems aimed at a use case where you know the keys of an object. But this may change.

    I wish Reactive was brought in the direction that it can be used as a 1:1 replacement for ES Map. This would make it easy for me: Reactive for Maps and Reference for the rest.

    I would also wish the name would change, to bring them closer. RMap would be fine - maybe I'll make one (derive from Reactive and add the enumeration methods).

    Summary

    The strong answer, with Vue 3, is "YES".

    However, the developer guidance can be made more straightforward, clearly stating which would be the logic for picking Reference or Reactive, and what eg. their runtime pros and cons are, without needing to read various blog posts.


    Edit: My current leaning is towards Ref, but I try to unwrap the reactivity quite early within the code, leading to just one .value within a computed.