Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store non-reactive data in Vuex?

I have data, that loaded on page once before VueJS-application init, and this data will not change for all time while html-page will not reload (classic CGI application, not SPA). Data example:

const nonReactiveObjectWithSomeNestedData = {
  a: 'a',
  b: {
    bb: 'bb',
    cc: { ccc: 'ccc' },
    dd: ['dd1', 'dd2']
  }
}

I am using this data in a few vue-components. It would be handy to store this data in Vuex namespaced module and to use Vuex-getters for wrapping same functionality for different vue-components. Is there any way to store this data not inside vuex state (reactivity not needed) but with ability to access from vuex-module's getter?

PS. Currently I am using storing non-reactive data inside vue-instance method, but now it is not enough, I need more global access to data (from two independent root-components).

like image 817
hedin Avatar asked Nov 23 '17 09:11

hedin


People also ask

How do I make my Vue data not reactive?

To avoid the overhead, you can use Object. freeze to prevent Vue from making your objects reactive. The example freezes the attributes nested property, which means Vue won't pick up any changes in them. Other properties may change and we want those to be picked up by the reactive system.

Is Vuex store reactive?

Vuex stores are reactive. When Vue components retrieve state from it, they will reactively and efficiently update if the store's state changes. You cannot directly mutate the store's state. The only way to change a store's state is by explicitly committing mutations.

How do I add data to my Vuex?

To create new data, you can use the insert , create , and new methods. They all insert new records to the Vuex Store but behave in a slightly different manner. The insert method will simply insert new records. You should pass an object containing records in data key to the method.


2 Answers

Freeze the object before adding it to the store:

Object.freeze(nonReactiveObjectWithSomeNestedData )

Vue won't make frozen objects reactive.

Note: you should freeze object before it comes into Vuex mutation/action:

this.$store.dispatch('moduleName/setNonReactiveObject', 
    Object.freeze(nonReactiveObjectWithSomeNestedData));

Inside mutation function the payload-parameter will be already reactive.

like image 175
Linus Borg Avatar answered Oct 02 '22 17:10

Linus Borg


One can also add a property _isVue to the object to avoid making it reactive.

commit('setNonReactiveObject', Object.assign(data, { _isVue: true })

This approach can be useful to make data non-reactive when there's no way to control how the data is stored in the store. For example when store data is completely replaced client-side to "hydrate" a server-side rendered website (e.g. Nuxt).

This is undocumented and might break in the future. At least the source code has a comment indicating that this property is used for this internally. And here is where the property is checked before observing the object.

like image 42
njam Avatar answered Oct 02 '22 17:10

njam