vue-dragula
vue-dragula copied to clipboard
Cannot reorder within the same bag in Vue 2.0
Based on https://github.com/Astray-git/vue-dragula/issues/19#issuecomment-254199811, indeed you cannot seem to reorder properly within the same bag.
I'm not yet sure if this is a Vue 2.0 issue or a vue-dragula issue. I'm trying to investigate, but I'm not that familiar with either projects. I'm also having trouble creating a small example, so please help me out @Astray-git if you can
Alright so this is happening because of Vue 2.0. This is not a bug, but expected behavior.
The key is with the comment here: http://archive.forum.vuejs.org/post/10869
Basically in order to get vue-dragula to work in Vue 2.0, you need to make sure that you pass to v-dragula the original prop for what you want to move around, but when iterating you need to work with a data() copy.
Here is an example of what I needed to do to get it to work in my project: https://github.com/amcsi/skill-builder/commit/a221dd6f07496374c137b1102881938f7fbc4294
Tagging @deiucanta because you are the one that brought this issue to our attention.
I need to re-open this, because it appears that I'm wrong.
Unfortunately doing the separation between prop and local changes aren't enough, because although it will work for dragging around, if anything else is changed in the parent, then all the moving around stuff will be overridden
If you look here https://github.com/vuejs/vue/issues/2873 you'll find:
Props Behavior
.once and .sync are deprecated. Props are now always one-way down. To produce side effects in the parent scope, a component needs to explicitly emit an event instead of relying on implicit binding.
Mutating a prop locally is now considered an anti-pattern, e.g. declaring a prop a and then set this.a = someOtherValue in the component. Due to the new rendering mechanism, whenever the parent component re-renders, the child component's local changes will be overwritten. In general, in 2.0 you should treat props as immutable. Most use cases of mutating a prop can be replaced by either a data property or a computed property.
So unfortunately there is no way to have changes go upwards without using events or having something passed down that can be used. Maybe this project is going to need some sort of new helper method that creates like some sort event-listener wrapped version of the elements so that when you pass that wrapped something to v-dragula and its splice() and such methods are called, then it would capture that and instead do some sort of event-based manipulation of the ancestor to change the data there. I don't know if that made sense.
So this issue is going to need to stay until further notice, and until then this plugin is unfortunately not usable in Vue 2.0
I don't know how I missed this one... so it's not compatible with 2.0 yet? :(
@vitobotta I made it compatible with Vue 2 now dev (still a WIP) and demo
I still can't quite grasp the concept of bags however. I wish @amcsi or someone else "in the know" could explain the relationships between the VM model, containers, bags service etc. What are the constraints. When must things be called and configured in the Vue/component life cycle for Vue2? Thanks :)
Unfortunately I don't quite know. It is like a group where items within a bag can only be moved to places where there's a bag with the same value. Kind of like a radio input's name attribute connects radio elements together. But it's best if you asked @Astray-git, because I hardly know anything about the project :(
A solution for vue2 DOM order, we must provide a key for v-for directive to update DOM order.
v-for="item in list" add :key="item.id" for object items, :key="item" for plain string.
see: https://vuejs.org/v2/guide/list.html#key
@Astray-git as far as I know, key is for optimizing re-rendering by not having to re-render bits where they their subdom is already in the correct place and in the correct state. And that using a key wouldn't solve the issue of the Vue2 caveat that you cannot mutate props coming from a parent, and that you have to use the event bus or vuex
that you have to use the event bus or vuex
How would you handle data mutation with vuex? By manually hooking into the dragula events and finding the moved element and the from and to models, am I right? Or there's some shortcut I'm missing here?
Any news on this issue? I was just trying vue-dragula for the first time in a small vue 2.2.4 project, but can't manage to get re-ordering items in a list working. I added :key but that seems not to make any difference.
You can try using vue2-dragula which has a fully customizable data model and supports a single bag model.
Ahhh, thanks Kristian! vue2-dragula works like a charm (:key must be defined though).
@josdejong Great to hear! You are very welcome to add your use case as an example in the new Wiki docs I've just added: Usage-examples
I'm sorry I'm lacking time to work out an example for the examples section. I use dragula just to do reordering of rows in a table, it's a simple use case.