I've some generic state like error
and session
in $store which I want to be accessed as computed property error
and session
in all components (including those in router). I know I should do like this:
var store = new Vuex.Store({
state: {
error: undefined,
session: JSON.parse(localStorage.getItem('session')),
},
mutations: {
error: function(state, error) {
state.error = error
},
session: function(state, session) {
state.session = session
},
},
})
var loginView = new Vue({
computed: {
error: {
get () {
return this.$store.state.error
},
set (val) {
this.$store.commit('error', val)
}
},
session: {
get () {
return this.$store.state.session
},
set (val) {
this.$store.commit('session', val)
}
},
},
})
var router = new VueRouter({
routes: [
{
path:'/login',
component: loginView,
},
],
})
var app = new Vue({
store,
router,
computed: {
error: {
get () {
return this.$store.state.error
},
set (val) {
this.$store.commit('error', val)
}
},
session: {
get () {
return this.$store.state.session
},
set (val) {
this.$store.commit('session', val)
}
},
},
})
As you can see, it's not DRY. What if I have 100 components in router and I want them to be able to have computed properties like this? Is there something to solve this? Maybe something like an option globals
in Vuex:
var store = new Vuex.Store({
globals: ['error', 'session'], // this will enable all components' computed property of error and session
state: {
error: undefined,
session: JSON.parse(localStorage.getItem('session')),
},
mutations: {
error: function(state, error) {
state.error = error
},
session: function(state, session) {
state.session = session
},
},
})
var loginView = new Vue({
computed: {
},
})
var router = new VueRouter({
routes: [
{
path:'/login',
component: loginView,
},
],
})
var app = new Vue({
store,
router,
computed: {
},
})
I do not see anywhere in the documentation that Vuex supports the set
of a computed value. If it did, you would probably be better off using mapGetters
.
If you want to follow the spirit of Vuex, I expect the best approach would be
to take advantage of mapGetters and mapActions/mapMutations and map your set
to an action/mutation.
You could also use a mixin to do this. I know you said you want to define these values globally (and you could do that with a global mixin), but you could stay DRY by defining a mixin with these properties and apply it where you actually need them.
Lastly you could use a global mixin. Take note of the caveats of using a global mixin in the linked documentation.
Vue.mixin({
computed: {
error: {
get () {
return this.$store.state.error
},
set (val) {
this.$store.commit('error', val)
}
},
session: {
get () {
return this.$store.state.session
},
set (val) {
this.$store.commit('session', val)
}
},
}
})
error
is a pretty generic name and you may want to rethink it if this is meant to be a property of every component.