Search code examples
laravelvuejs2vuedraggable

VueDraggable and Laravel


I'm confused as how to correctly use vueDraggable together with Laravel.

I can drag and sort the elements in the browser but the array is not changing (when I check in the console)/ it seems to me the changes aren't reflected in the array. Shouldn't the array index numbers change after moving items?

In the overview.blade.php I have the component:

<qm-draggable :list="{{ $mylaravelarray }}"></qm-draggable>

In the qm-draggable.vue I have:

<template>
  <draggable group="fragenblatt" @start="drag=true" @end="endDrag" handle=".handle">
    <li v-for="(item, index) in draggablearray" :key="item.index">
        // list items here
    </li>
  </draggable>
</template>

<script>
data() {
    return {
      draggablearray:{},
    };
  },
  props: {
    list: Array,
  },
  mounted: function(){
    this.draggablearray = this.list; // create a new array so I don't alter the prop directly.
  },
  [..]
  </script>

In the documentation it says, one way to pass the array is:

value

Type: Array

Required: false

Default: null

Input array to draggable component. Typically same array as referenced by inner element v-for directive. This is the preferred way to use Vue.draggable as it is compatible with Vuex. It should not be used directly but only though the v-model directive:

<draggable v-model="myArray">

But where do I do that? in overview.blade.php or in the component (.vue), or both?


Solution

  • Try setting v-model on your draggable as that's what will update draggablearray.

    Also if draggablearray is supposed to be an array, initialise it as one, so draggablearray:{} should be draggablearray:[].

    new Vue({
      el: '#app',
      data: () => {
        return {
          drag: false,
          draggablearray: [{
            id: 1,
            name: "1"
          }, {
            id: 2,
            name: "2"
          }, {
            id: 3,
            name: "3"
          }]
        }
      }
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js">
    </script>
    <script src="https://cdn.jsdelivr.net/npm/sortablejs@1.7.0/Sortable.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.16.0/vuedraggable.min.js"></script>
    
    <div class="container">
      <div id="app">
    
        <draggable v-model="draggablearray" group="fragenblatt">
          <li v-for="(item, index) in draggablearray">
            {{item.name}}
          </li>
        </draggable>
    
        {{draggablearray}}
    
      </div>
    
    </div>
    
    
    <script type="text/x-template" id="tree-menu">
    
      <div class="tree-menu">
        <div class="label-wrapper">
          <div :style="indent" :class="labelClasses" @click.stop="toggleChildren">
            <i v-if="nodes" class="fa" :class="iconClasses"></i>
            <input type="checkbox" :checked="selected" @input="tickChildren" @click.stop /> {{label}}
          </div>
        </div>
    
        <draggable v-model="nodes" :options="{group:{ name:'g1'}}">
          <tree-menu v-if="showChildren" v-for="node in nodes" :nodes="node.nodes" :label="node.label" :depth="depth + 1" :selected="node.selected" :key="node">
          </tree-menu>
        </draggable>
    
      </div>
    
    </script>