Another VueX State Question (Ithought I knew how it worked)
-
I am having a problem which I can’t seem to solve. First some Code:
<template> <div> <q-input name="email" v-model="user.email" /> <q-input name="userName" v-model="user.userName" /> </div> </template> <script> export default { name: 'UserDetail', props: { id: String }, computed: { user: { get () { return this.$store.state.users.user }, set (value) { this.$store.dispatch('users/updateUser', this.id, value) } } } } </script>
And here the store action:
export function updateUser ({ commit }, id, user) { if (id !== user.id) { console.log('Id und User.Id stimmen nicht überein') } else { api.put(`/User/${id}`, user).then(response => { commit('upsertUser', response.data) }).catch(error => { console.log(error) }) } }
Mutation:
export const upsertUser = (state, user) => { const idx = state.userList.findIndex(x => x.id === user.id) if (idx !== -1) { state.userList[idx] = user } else { state.userList.push(user) } if (state.user?.id === user.id) { state.user = user } }
Now as far as I can tell this adheres to the vuex recommendet way of doing things like this (https://vuex.vuejs.org/guide/forms.html#two-way-computed-property)
But I always get the Error:
do not mutate vuex store state outside mutation handlers
I can not figure out how to do this. Can someone point me in the right direction?
-
Thats because the get/set computed vuex call ‘trick’ only works for single properties, not for objects ( user) with properties (email & username).
See the example link, it uses a single property not an object.
-
@dobbel Thanks, ok that explains why it is not working. What would be the best solution? There are always only very basic or simple examples always only handling simple objects.
-
Here’s a discussion about it:
https://forum.vuejs.org/t/vuex-best-practices-for-complex-objects/10143/46Personally I would try this first:
https://github.com/vuex-orm/vuex-ormOr this one:
https://github.com/maoberlehner/vuex-map-fields#nested-properties -
@dobbel Thank you very much. What are your experiences with the vue-orm? I had planed to look into it (saw a Tutorial on QuasarCast.com about it). But looking at the Github project this seems under heavy development, which makes me feel a little uncomfortable using it in production … On the other hand, I am using quasar next on production, but that is at least in Beta and the API should be mostly stable.
Also since I am using quasar next with vue3 would the composition API maybe be a solution to my problem? -
Another Note:
I change the get function fromget () { return this.$store.state.users.user }
To:
get () { return { ...this.$store.state.users.user } }
And now I do not get the Error anymore, but the set only works if I change the whole User Object. It does not get called when I change only a property on the user.
I guess I would have to add a change and input event handler then on each property, to save the changes. -
Also since I am using quasar next with vue3 would the composition API maybe be a solution to my problem?
Will probably cause more issues then it will fix things right now ( not always vue3 or Quasar related). I will start using vue3 when all my other vue plugins/repo’s I use are migrated to vue3.
What are your experiences with the vue-orm?
I tried it and it seemed to work fine.
-
@dobbel
I actually integrated it in my application and in my first tests it seems to work fine. It did not directly fix my problem (which seems like what I was trying to do is a vue anti pattern). I still do have some quirky side effects, but I am also just learning vue. Thank you for that awesome tip to vue-orm