Reputation: 14198
I would like to assign setter methods via mapState
. I currently use a workaround where I name the variable that I am interested in (todo
) as a temporary name (storetodo
) and then refer to it in another computed variable todo
.
methods: {
...mapMutations([
'clearTodo',
'updateTodo'
])
},
computed: {
...mapState({
storetodo: state => state.todos.todo
}),
todo: {
get () { return this.storetodo},
set (value) { this.updateTodo(value) }
}
}
I would like to skip the extra step and define the getter, setter directly within mapState
.
Why would I want to do this?
The normal approach would be use mapMutations
/mapActions
& mapState
/mapGetters
without the computed get/set combination that I have illustrated above and to reference the mutation directly in the HTML:
<input v-model='todo' v-on:keyup.stop='updateTodo($event.target.value)' />
The getter/setter version allows me to simply write:
<input v-model='todo' />
Upvotes: 26
Views: 23098
Reputation: 10717
Another way of approaching that is using store mutations
like below:
//in your component js file:
this.$store.commit('setStoretodo', storetodo)
Assuming you define setStoretodo
in mutations of your vuex store instance (which is something recommended to have anyways):
//in your vuex store js file:
state:{...},
actions: {...}
...
mutations: {
setStoretodo(state, val){
state.storetodo = val
},
...
}
...
That keeps the property reactive as mapState
will grab the updated value and it will be rendered automatically.
Surely, that's not as cool as just writing this.storetodo = newValue
, but maybe someone will find that helpful as well.
Upvotes: 1
Reputation: 827
This is my current workaround. Copied from my personal working project
// in some utils/vuex.js file
export const mapSetter = (state, setters = {}) => (
Object.keys(state).reduce((acc, stateName) => {
acc[stateName] = {
get: state[stateName],
};
// check if setter exists
if (setters[stateName]) {
acc[stateName].set = setters[stateName];
}
return acc;
}, {})
);
In your component.vue file
import { mapSetter } from 'path/to/utils/vuex.js';
export default {
name: 'ComponentName',
computed: {
...mapSetter(
mapState({
result: ({ ITEMS }) => ITEMS.result,
total: ({ ITEMS }) => ITEMS.total,
current: ({ ITEMS }) => ITEMS.page,
limit: ({ ITEMS }) => ITEMS.limit,
}),
{
limit(payload) {
this.$store.dispatch({ type: TYPES.SET_LIMIT, payload });
},
},
)
},
}
now you can use the v-model bindings. l
Upvotes: 6
Reputation: 31362
You can't use a getter/setter format in the mapState
what you can try is directly return the state in your get()
and remove mapState
from the computed property
computed: {
todo: {
get () { return this.$store.state.todos.todo},
set (value) { this.updateTodo(value) }
}
}
Here is a related but not same JsFiddle example
Upvotes: 33