1. 程式人生 > 程式設計 >vue實現列表拖拽排序的功能

vue實現列表拖拽排序的功能

  在日常開發中,特別是管理端,經常會遇到要實現拖拽排序的效果;這裡提供一種簡單的實現方案。

  此例子基於vuecli3

首先,我們先了解一下js原生拖動事件:

  在拖動目標上觸發事件(源元素):

  • ondragstart- 使用者開始拖動元素時觸發
  • ondrag - 元素正在拖動時觸發
  • ondragend - 使用者完成元素拖動後觸發  

  釋放目標時觸發的事件:

  • ondragenter- 當被滑鼠拖動的物件進入其容器範圍內時觸發此事件
  • ondragover- 當某被拖動的物件在另一物件容器範圍內拖動時觸發此事件
  • ondragleave- 當被滑鼠拖動的物件離開其容器範圍內時觸發此事件
  • ondrop- 在一個拖動過程中,釋放滑鼠鍵時觸發此事件

 基於js的原生拖拽事件,本次實現的拖拽排序的原理大概是:滑鼠按住列表某一項開始拖動時觸發ondragstart事件,將該拖動項用變數記錄下來;

接著拖拽過程中,該拖動項經過列表其他項時,觸發ondragenter事件,同樣記錄該拖動項最後經過的列表其他項的資料,最後在ondragend 事件中

將陣列列表刪掉一開始ondragstart事件記錄的拖動項,並將刪掉的資料插入ondragenter事件最後記錄的位置,完成拖動排序。

 具體程式碼如下:

<template>
  <div class="test_wrapper" @dragover="dragover($event)">
    <transition-group class="transition-wrapper" name="sort">
      <div v-for="(item) in dataList" :key='item.id' class="sort-item"
        :draggable="true"
        @dragstart="dragstart(item)"
        @dragenter="dragenter(item,$event)"
        @dragend="dragend(item,$event)"
        @dragover="dragover($event)"
      >
        {{ item.label }}
      </div>
    </transition-group>
  </div>
</template>

<script lang="ts">
  import {Vue,Component,Prop,Watch} from "vue-property-decorator";
  import { addWebsite } from '@/api'
  @Component({
    components: {}
  })
  export default class Test extends Vue {

    oldData: any = null; // 開始排序時按住的舊資料
    newData: any = null; // 拖拽過程的資料

    // 列表資料
    dataList:any = [
      { id:1,label:'測試一號' },{ id:2,label:'測試二號' },{ id:3,label:'測試三號' },{ id:4,label:'測試四號' },];

    dragstart(value: any) {
      this.oldData = value
    }

    // 記錄移動過程中資訊
    dragenter(value: any,e: any) {
      this.newData = value
      e.preventDefault()
    }

    // 拖拽最終操作
    dragend(value: any,e: any) {
      if (this.oldData !== this.newData) {
        let oldIndex = this.dataList.indexOf(this.oldData)
        let newIndex = this.dataList.indexOf(this.newData)
        let newItems = [...this.dataList]
        // 刪除老的節點
        newItems.splice(oldIndex,1)
        // 在列表中目標位置增加新的節點
        newItems.splice(newIndex,this.oldData)
        this.dataList = [...newItems]
      }
    }


    // 拖動事件(主要是為了拖動時滑鼠游標不變為禁止)
    dragover(e: any) {
      e.preventDefault()
    }


  };
</script>

另外

  為了實現拖動的動畫效果,這裡用到了transition-group元件,如上面程式碼顯示,將transition-group元件的屬性name設為‘sort';並新增以下程式碼;

    .sort-move {
      transition: transform 0.3s;
    }

注意:為了讓transition有效果出現,v-for渲染的資料列表必須有key屬性,且該key屬性不可設為index;

最終效果如下:

vue實現列表拖拽排序的功能

以上就是vue實現列表拖拽排序的功能的詳細內容,更多關於vue 拖拽排序的資料請關注我們其它相關文章!