Home > other >  How to reuse Vuex state properties across different stores?
How to reuse Vuex state properties across different stores?

Time:06-23

I'm trying to reuse the isLoading state property across multiple stores. I expect it to work by having one external object containing states and mutations, and when I import them into some store, this store will automatically be merged with the states and mutation contained in this object. Different from modules that generate a new store, I expect this object to be merged with the store that imports it.

Ex:

// load-mixin.js
export default {
  state: {
    isLoading: false,
    isLoaded: false,
  },
  mutations: {
    setIsLoading(state, isLoading) {
      state.isLoading = isLoading
    },
    setIsLoaded(state, isLoaded) {
      state.isLoaded = isLoaded
    },
  }
}
// store1.js
import loadState from 'load-mixin'

export default {
  namespaced: true,
  // this should have the states and mutation from `load-mixin`
  mixins: [
    loadState
  ],
}
// store2.js
import loadState from 'load-mixin'

export default {
  namespaced: true,
  // this should have the states and mutation from `load-mixin`
  mixins: [
    loadState
  ],
}

But looks like there aren't mixins in Vuex. Is there Vuex way of achieving this?

CodePudding user response:

Considering that each store needs to have its own isLoading state property, this can be done with helper function:

const withIsLoading = storeConfig => deepMerge({}, storeConfig, {
  state: {
    isLoading: false,
    isLoaded: false,
  },
  mutations: {
    setIsLoading(state, isLoading) {...},
    setIsLoaded(state, isLoaded) {...},
  },
});

and

export default withIsLoading({
  namespaced: true,
})

Where deepMerge is any deep merge implementation, e.g. Lodash merge. In case there are multiple helpers like withIsLoading(withSomethingElse({... })), they can be composed with Lodash flow/flowRight or a similar function to avoid nesting.

Notice that Vuex store state can be defined as factory function instead of an object, which is generally a good practice. This needs to be considered for a more universal store definition that isn't limited to plain objects specified as state.

Also a Vuex plugin can contain logic that can be reused between stores.

CodePudding user response:

Loading and loaded state you will used for side-effects. so you can get this in actions. And dont access state directly make getters for read value and mutation for setting value. you will do by below

someAction ({ dispatch, commit, getters, rootGetters }) {
            getters.someGetter // -> 'foo/someGetter'
            rootGetters.someGetter // -> 'someGetter'
            rootGetters['bar/someGetter'] // -> 'bar/someGetter'
   
    
            commit('someMutation') // -> 'foo/someMutation'
            commit('someMutation', null, { root: true }) // -> 'someMutation'
          },
  • Related