Reputation: 1523
I have getter in vuex which returns item from list
const store = new Vuex.Store({
state: { arr: {
1: {name: 'one', attr: true},
2: {name: 'two', attr: false}
},
mutations: {
setArrItemName(state, id, name) {
Vue.set(state.arr, id, name);
}
},
getters: {
arrItemById(state, getters) => (id) => {
const item = state.arr[id];
if(item) return item;
return {
name: 'default', attr: true
};
}
}
})
If I output it in template
{{ $store.state.arr[1]['name'] }}
it updates fine when another part calls
this.$store.commit('setArrItemName', 1, 'new name');
But if template contains
{{ $store.getters.arrItemById(1).name }}
Then it's not updated
Problem: this getter is used in different places and I do not want to duplicate this code
<template v-if='$store.state.arr[id]'>
{{ $store.state.arr[id].name }}
</template>
Default
<template v-else>
</template>
If 'default' some day changes, or any other attribute of default
object then it should be updated in different places.
Upvotes: 11
Views: 27609
Reputation: 31362
Try using computed properties for accessing your getters. First, import the mapGetters
function from Vuex:
import {mapGetters} from 'vuex';
Then, add computed properties for the getters you want as follows:
computed: {
...mapGetters({
getterName: 'your-getter-name-in-store'
})
}
We use a spread operater ( ...
) while using the mapGetters
helper; you can read more about why here.
Then, in your template, use {{ getterName }}
.
This also overcomes your problem of code duplication, as you won't need to use this.$store.getters
everywhere.
Upvotes: 9
Reputation: 23473
I don't know if this typo is just in the question, or in your program too...
from above
const store = new Vuex.Store({
state: { arr: {
1: {name: 'one', attr: true},
2: {name: 'two', attr: false}
},
mutations: {
...
should be
const store = new Vuex.Store({
state: { arr: {
1: {name: 'one', attr: true},
2: {name: 'two', attr: false}
} // missing this closing brace on object arr
},
mutations: {
...
That might explain the getter problem.
Upvotes: 0
Reputation: 942
You can't get reactive on getter which is not pure. You can create a computed property on local.
Sources : https://github.com/vuejs/vuex/issues/145#issuecomment-230488443
I made some research, and you can use computed function with a getter inside :
computed: {
arr() {
return this.$store.getters.arrItemById(this.id);
}
},
Here is a jsfiddle example.
Upvotes: 3