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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With