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

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

3 Comments

And what if we need to change that object later but still don't want the reactivity?
1. make a copy const copy = { ..original }, 2. change that copy, 3. freeze the copy, 4. replace original in store with the copy.
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).
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.

Comments

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

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.