vueリストのドラッグ&ドロップのソート機能を実現します。


日常開発の中で、特に管理側は、ドラッグ&ドロップの効果を実現することがよくあります。ここでは簡単な実現方法を提供します。
この例はvuecli 3に基づいています。
まず、js原生ドラッグ事件について調べてみます。
ドラッグ先でイベントをトリガする (ソース要素):
  • ondragstart - ユーザが要素をドラッグし始めると、トリガ
  • が起動されます。
  • ondrag-要素がドラッグされているときにトリガ
  • ondragent-ユーザーが要素をドラッグした後、トリガ
  • ターゲットをリリースする時にトリガするイベント:
  • 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, 0, this.oldData)
            this.dataList = [...newItems]
          }
        }
    
    
        //     (                 )
        dragover(e: any) {
          e.preventDefault()
        }
    
    
      };
    </script>
    また
    ドラッグしたアニメーション効果を実現するために、ここではtrosition-groupコンポーネントを使用して、上のコードの表示のように、trnsition-groupコンポーネントの属性nameを「sort」に設定します。以下のコードを追加します。
    
        .sort-move {
          transition: transform 0.3s;
        }
           注意:transionを効果的に表示するためには、v-forレンダリングされたデータリストにkey属性が必要であり、かつ、key属性はindexに設定できません。 
    最終効果は以下の通りです。

    以上はvueのリストのドラッグ&ドロップを実現する機能の詳細です。vueのドラッグ&ドロップに関する資料は他の関連記事に注目してください。