Sortable Demo

by kabanoki

HTML

<!DOCTYPE html>
  <head>
    <title>Document</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <script src="https://unpkg.com/[email protected]/dist/vue.global.prod.js"></script>
    <script src="//cdn.jsdelivr.net/npm/[email protected]/Sortable.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuedraggable.umd.min.js"></script>

  </head>
  <body>
    <div id="app">
        <div class="row">
          <div class="col-2">
            <div class="form-group">
              <div
                class="btn-group-vertical buttons"
                role="group"
                aria-label="Basic example"
              >
                <button class="btn btn-secondary" @click="add">Add</button>
                <button class="btn btn-secondary" @click="replace">Replace</button>
              </div>
      
              <div class="form-check">
                <input
                  id="disabled"
                  type="checkbox"
                  v-model="enabled"
                  class="form-check-input"
                />
                <label class="form-check-label" for="disabled">DnD enabled</label>
              </div>
            </div>
          </div>
      
          <div class="col-6">
            <h3>Draggable {{ draggingInfo }}</h3>
            <table class="table">
               <tbody is="vue:draggable"
                tag="tbody"
                v-model="list"
                :item-key="name"
                :disabled="!enabled"
                class="list-group"
                ghost-class="ghost"
                :move="checkMove"
                @start="dragging = true"
                @end="dragging = false"
              >
                <template #item="{element:item}">
                  <tr>
                    <td>{{item.name}}</td>
     ...

CSS

<style scoped>
.buttons {
  margin-top: 35px;
}
.ghost {
  opacity: 0.5;
  background: #c8ebfb;
}
.not-draggable {
  cursor: no-drop;
}
</style>

JavaScript

Vue.createApp({
    name: "simple",
  display: "Simple",
  order: 0,
  components: {
    draggable: window['vuedraggable']
  },
    data() {
    return {
      enabled: true,
      list: [
        { name: "John", id: 0 },
        { name: "Joao", id: 1 },
        { name: "Jean", id: 2 }
      ],
      dragging: false
    };
  },
  computed: {
    draggingInfo() {
      return this.dragging ? "under drag" : "";
    }
  },
  methods: {
    add: function() {
      this.list.push({ name: "Juan " + id, id: id++ });
    },
    replace: function() {
      this.list = [{ name: "Edgard", id: id++ }];
    },
    checkMove: function(e) {
      window.console.log("Future index: " + e.draggedContext.futureIndex);
    }
  }

  }).mount("#app");