4

Is there a way to use Vue.Draggable lists with computed variables in a Vuex Store? I'm fairly new to VueJS and this is my current component setup:

// Template
<draggable class="list-group" :list="list1" group="people">
  <div
    class="list-group-item"
    v-for="(element, index) in list1"
    :key="element.id"
  >{{ element.name }} ({{ element.list }}) ({{ index }})</div>
</draggable>

// Script
computed: {
  list1: {
    return this.$store.getters.listItems.filter(item => item.list === 1)
  }
}

// Store
const getters = {
  listItems: (state) => {
    return state.items
  }
}

Without computed variables, everything works fine. When using computed variables, I can drag list items between lists, however the UI won't update because it's computed from the store. Basically, what I need is to display multiple lists based on an input file (json). These lists have list items that can be dragged between different lists (with Vue.Draggable). Also, the user can create new list items / delete existing list items. What's the best way to achieve this?

Thank you in advance.

  • Computed property should be a function that returns some value. – Belmin Bedak Nov 18 '19 at 16:13
  • The computed property does return a value, or am I wrong? The list items are displayed correctly once the app loads. This is the function: return this.$store.getters.listItems.filter(item => item.list === 1) – user2307798 Nov 18 '19 at 18:28

2 Answers2

0

In a complex draggable use-case, also using vuex, I ended up creating a variable in state called 'changes', and every time something changes, it gets incremented (through a vuex mutation). The data that's linked to dragging is in data, not in the store. I manually sync the two.

I use this - through a watcher - to trigger a rerender of my base component with completely fresh data.

This solution is ugly, and likely won't be necessary in vue3.

Katinka Hesselink
  • 3,961
  • 4
  • 20
  • 26
0

You probable need to do the following:

  1. Have your draggable div into a new component

  2. On this new component, have this @change.self="handleDragAndDrop($event)"

  3. Handle the D&D

handleDragAndDrop: function (event){
    const eventType = Object.keys(event)[0];
    const chosenFrame = event[eventType].element;
    
    store.dispatch(
        "updateFramesOrder",
        {
            event: event,
            listItemId: this.$props.itemId,
        }
    );
}
  1. Finally in the store create the updateFramesOrder action that changes the list accordingly.

Hope it helps!

Pontios
  • 2,377
  • 27
  • 32