https://codesandbox.io/s/github/lzinga/store-test
I have looked at all issues that have to do with vuex and tried to find a fix among them, the one that seems to be the most related is issue #710 . However none of the posts seemed to provide an example project showing this issue so they never seemingly had any accepted answer or fix. Mostly just stated to use v-model which I have been using. So hopefully having this example helps.
Both the parents and children elements allow being ordered in the list.
I would try updating index file to use VUEX mapGetters and mapActions for getting and setting data from the store. I'm not sure exactly why it works for the parents but not the children, but the fact that you are referencing the state directly from the store might be the wrench in your gears.
Also, I noticed in your store you have two mutators that literally do the same thing so I would get rid of one of those just to simplify things.
I am following what the examples state to do in the nested with vmodel example. Which seems to work perfectly fine in their code unless I am missing something which is totally possible. I am somewhat new to vuejs and nuxt frameworks. Any way you can explain a little more of using mapGetters and mapActions in this use case? How would that be different from how it is currently being done considering I am using a computed property in index.vue?
You are indeed correct about the mutators though, I copied it out of a different project and in that one they did indeed do more than what is visible in this project and just kept the difference when creating an example for others of the issue.
Update
I tried the following computed property and it does the same thing which I think is what you were requesting, just with out the mapping.
index.vue
computed: {
chapters: {
get() {
return this.$store.getters["chapters.edit/chapters"]
},
set(value) {
this.$store.dispatch('chapters.edit/updateChapters', value)
}
}
},
chapters.edit.js
export const getters = {
chapters: state => {
return state.chapters
}
}
When debugging in firefox and setting a breakpoint on the set option of the computed property it never breaks when moving a sub element. When moving a parent it works perfectly fine.
I cant speak to the example you're following but read this page, and particularly the bottom of it: https://vuex.vuejs.org/guide/getters.html
The jist is that if you import your state variable via mapgetters its saved as a local computed property. Then you should be able to manipulate it in theory, the use mapActions to call the action to call the mutator to save the new data after you have done your manipulations.
Something is writing directly to the store state I'm guessing because you're mapping / using the data directly from the state. So when sortable changes something it updates the state directly which is causing the error.
I'm not super advanced with this stuff yet either but this is just my take on what I'm seeing. Hopefully its some help to you but I make no promises ;)
The example is part of this library so figured it should work considering it works in their demo pages too. However something seems different. I have gone ahead and tried what you said though and used the ...mapGetters and ...mapActions but the same thing happens.
computed: {
...mapGetters({
storeChapters: 'chapters.edit/chapters'
}),
chapters: {
get() {
return this.storeChapters
},
set(value) {
this.updateChapters(value)
}
}
},
methods: {
...mapActions({
updateChapters: 'chapters.edit/updateChapters',
}),
},
I also tried setting the model of the nested-drag.vue directly to the mapped getter storeChapters property and still didn't work.
I quickly downloaded the source examples in the library and debugged them to see if they behaved in the same way as my test environment where the issue is. The examples do the same as mine in that it executes the computed properties set function when moving a parent but not when moving a child. When looking at the vuex state while moving things around the only time the state updates is when a parent is moving. But while moving a child it doesn't update the vuex state until a parent is moved or you manually run the update. Not sure what that tells me just yet but figured I would write it out.
Oh and thanks for the help, this is basically halting my entire project and any help is appreciated.
Alright, so if I change the computed property to -
computed: {
chapters: {
get() {
return JSON.parse(JSON.stringify(this.$store.getters["chapters.edit/chapters"]))
},
set(value) {
this.$store.dispatch('chapters.edit/updateChapters', value)
}
}
},
It no longer complains about mutating the store and allows me to move items around, however it does not update the child elements until I move a parent element which triggers the set(value) method of the computed property. I have tried passing through some events but no luck so far.
Though I don't think the code above is really efficient and worth while continuing with considering it has to convert and parse every time it accesses the computed property.
UPDATE
Alright, so I seem to have found a work around for my use case, instead of a recursive component I have just added a second
If you are interested in seeing these changes you can view them at this commit change
I am closing this one. Not related to vue.draggable by itself but to how to integrate with Vuex.
The most probable reason for all those "Error: [vuex] do not mutate vuex store state outside mutation handlers" error is the strict mode setting in the store.
The Vue.Draggable examples do not use strict mode for the store and that is why there are no errors when the store state is mutated within the draggable (which happens every time you use the :list property to pass a store state to the draggable).
If you pay close attention you will see that in the examples the top level elements of the tree are passed via :value to the draggable and via @input back to the store (that is why it works for the top level elements), while the nested elements are passed to the draggable via its :list prop.
I think the nested example should be extended to cover the case when we have strict mode set for the store (which is recommended during development).
Most helpful comment
The most probable reason for all those "Error: [vuex] do not mutate vuex store state outside mutation handlers" error is the strict mode setting in the store.
The Vue.Draggable examples do not use strict mode for the store and that is why there are no errors when the store state is mutated within the draggable (which happens every time you use the
:listproperty to pass a store state to the draggable).If you pay close attention you will see that in the examples the top level elements of the tree are passed via
:valueto the draggable and via@inputback to the store (that is why it works for the top level elements), while the nested elements are passed to the draggable via its:listprop.I think the nested example should be extended to cover the case when we have strict mode set for the store (which is recommended during development).