How to store non-reactive data in Vuex?
Asked Answered
G

4

17

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).

Girl answered 23/11, 2017 at 9:51 Comment(0)
I
32

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.

Idoux answered 23/11, 2017 at 10:7 Comment(3)
And what if we need to change that object later but still don't want the reactivity?Speaking
1. make a copy const copy = { ..original }, 2. change that copy, 3. freeze the copy, 4. replace original in store with the copy.Idoux
Right now I'm using vuex 3.0.1 and the payload-parameter is not "already reactive" inside action and mutation functions (but afterwards of course).Rabiah
U
6

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.

Underlayer answered 11/5, 2019 at 14:10 Comment(0)
C
1

I was able to remove the "reactiveness" by doing something like this

// create new variable and remove reactiveness, does a deep clone
var someNewNonReactiveVar = JSON.parse(JSON.stringify(someReactiveVar));
Chunky answered 26/8, 2019 at 21:42 Comment(0)
G
0

In mutation file you can deep clone the payload that you don't want to be reactive

import _ from 'lodash';

    [mutationTypes.SET_INITIAL_STATE](state, payload) {
    // In order to make sure that this property is non-reactive deep clone it
    state.initialState = _.cloneDeep(payload)
}

This way the initialState or whatever property you're adding to the state, won't be reactive.

Grew answered 11/11, 2020 at 7:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.