How to store a map of values in a reactive object in Vue 2?

Viewed 1743

I’m working on a web application users add objects to a database. The structure of these objects is fixed, but some of them have a data property that contains a map of strings, for example { title: "Test", description: "Description" }. Both the keys and the values in this map are user-defined, so theoretically users can define keys like constructor, __proto__ and __ob__.

I want to store the database objects in the data of a Vue 2 component, so they will be made reactive. I'm having trouble to decide which data type I should use for the data property. The following options come to my mind:

  • Usually I would use a null-prototype object for the data property. So create it using Object.create(null). This would make sure that keys like constructor and __proto__ would work without problems, but there would be problems with the __ob__ property added by Vue. I’m not sure if deleting that property would cause any trouble for Vue, but I guess it will just add the property again on the next occasion.
  • The proper way to do it would be to use ES6 maps. But as far as I understand, Vue 2 doesn’t support these yet, so they won’t be reactive.
  • I could use or write a custom class that has an interface similar to ES6 maps but internally stores the data in an array or something else that Vue’s reactivity system supports. There seem to be plenty of ES6 map polyfills out there, but I’m not sure which ones of them would work flawlessly with Vue’s reactivity system.

What would be the best way to store such a map of values with user-defined keys in a reactive Vue 2 object?

1 Answers

In the end I wrote my own class that has an interface similar to ES6 maps, so that migrating to ES6 maps will be straightforward when I migrate to Vue 3 one day.

In my class, I'm storing the map entries in an array of [string, string] tuples. I'm using an array because Vue 2 has good reactivity support for arrays, and I'm using tuples because then the array's iterator has the same data type as an ES6 map iterator. You can find the source code of my class here.

Other solutions to the problem were suggested in the comments:

  • Use a prefix for the property keys
  • Use the Vue 3 composition API in Vue 2 using a plugin
Related