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 Map
s and Set
s?
We can use JavaScript maps and sets as reactive properties in Vue.
One of Vue's most distinct features is the unobtrusive reactivity system. Component state are reactive JavaScript objects. When you modify them, the view updates. It makes state management simple and intuitive, but it's also important to understand how it works to avoid some common gotchas.
vue-google-maps, which has been updated for Vue. js 2, provides Vue. js applications with tools to utilize these APIs. It comes with a well-rounded set of components for interacting with Google Maps as well as two-way data binding.
Props and data are both reactiveWith Vue you don't need to think all that much about when the component will update itself and render new changes to the screen. This is because Vue is reactive. Instead of calling setState every time you want to change something, you just change the thing!
Vue.js does not support reactivity on Map
and Set
data types (yet?).
The feature ticket has some discussion and this work around (by user "inca"):
Sets and Maps are not observable by Vue. In order to use those — either in
v-for
, or in computed properties, methods, watchers, template expressions, etc. — 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 thatSet
is updated: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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With