Vue實用功能之實現拖拽元素、列表拖拽排序

Vue實現拖拽元素、列表拖拽排序

需求:
    1、左右兩個容器,左邊和右邊的元素可以拖動互換
    2、列表拖拽排序

組件使用

Vue.Draggable是一款基於Sortable.js實現的vue拖拽插件支持移動設備、拖拽和選擇文本、智能滾動,可以在不同列表間拖拽、不依賴jQuery為基礎,vue2過渡動畫兼容、支持撤銷操作,總之是一款非常優秀的vue拖拽組件

npm或yarn安裝方式

yarn add vuedraggable
npm i -S vuedraggable
<template>
  <div>
    <!--使用draggable組件-->
    <div class="itxst">
      <div>自定義控制拖拽和停靠</div>
      <div class="col">
        <!-- 左邊容器 -->
        <!-- 
          group: :group= "name",相同的組之間可以相互拖拽或者 { name: "...", pull: [true, false, 'clone', array , function], put: [true, false, array , function] }
          ghostClass::ghostClass="ghostClass" 設置拖動元素的占位符類名,你的自定義樣式可能需要加!important才能生效,並把forceFallback屬性設置成true
          chosenClass :ghostClass="hostClass" 被選中目標的樣式,你的自定義樣式可能需要加!important才能生效,並把forceFallback屬性設置成true
          filter :filter=".unmover" 設置瞭unmover樣式的元素不允許拖動
          -->
        <draggable v-model="arr1" group="itxst" ghostClass="ghost" chosenClass="chosen" filter=".forbid" animation="300"
          :move="onMove">
          <transition-group>
            <div :class="item.id==1?'item forbid':'item'" v-for="item in arr1" :key="item.id">{{item.name}}</div>
          </transition-group>
        </draggable>
      </div>
      <!-- 右邊容器 -->
      <div class="col">
        <draggable v-model="arr2" group="itxst" ghostClass="ghost" chosenClass="chosen" filter=".forbid" animation="300"
          :move="onMove">
          <transition-group>
            <div :class="item.id==1?'item forbid':'item'" v-for="item in arr2" :key="item.id">{{item.name}}</div>
          </transition-group>
        </draggable>
      </div>
    </div>
  </div>
</template>
<script>
  //導入draggable組件
  import draggable from 'vuedraggable'
  export default {
    //註冊draggable組件
    components: {
      draggable,
    },
    data() {
      return {
        //定義要被拖拽對象的數組
        arr1: [{
            id: 1,
            name: 'www.itxst.com(不允許停靠)'
          },
          {
            id: 2,
            name: 'www.jd.com'
          },
          {
            id: 3,
            name: 'www.baidu.com'
          },
          {
            id: 5,
            name: 'www.google.com'
          },
          {
            id: 4,
            name: 'www.taobao.com(不允許拖拽)'
          }
        ],
        arr2: [{
            id: 11,
            name: '微軟'
          },
          {
            id: 12,
            name: '亞馬遜'
          },
          {
            id: 13,
            name: '京東'
          },
          {
            id: 15,
            name: '谷歌'
          },
          {
            id: 14,
            name: '蘋果'
          }
        ]
      };
    },
    methods: {
      //move回調方法
      onMove(e, originalEvent) {
        console.log(e)
        console.log(originalEvent)
        //不允許停靠
        if (e.relatedContext.element.id == 1) return false;
        //不允許拖拽
        if (e.draggedContext.element.id == 4) return false;
        return true;
      },
    },
  };
</script>
<style scoped>
  /*定義要拖拽元素的樣式*/
  .drag {
    background-color: blue !important;
    border: solid 3px red;
  }

  .chosen {
    background-color: #333 !important;
    color: #fff;
  }

  .ghost {
    background-color: red !important;
  }

  .itxst {
    margin: 10px;
    text-align: left;
  }

  .col {
    width: 40%;
    flex: 1;
    padding: 10px;
    border: solid 1px #eee;
    border-radius: 5px;
    float: left;
  }

  .col+.col {
    margin-left: 10px;
  }

  .item {
    padding: 6px 12px;
    margin: 0px 10px 0px 10px;
    border: solid 1px #eee;
    background-color: #f1f1f1;
    text-align: left;
  }

  .item+.item {
    border-top: none;
    margin-top: 6px;
  }

  .item:hover {
    background-color: #fdfdfd;
    cursor: move;
  }
</style>

補充:排序動畫

如果不熟悉Vue的transition-group,請先學習Vue的列表的排序過渡,這裡不再贅述。

為瞭便於和上面的代碼進行比較,同樣一次性把全部代碼貼出,可以看到代碼變動並不大,隻需把HTML的ul元素改為transition-group,在methods中新增shuffle方法,在CSS中新增一個過渡transition: transform .3s;即可實現開頭第一張圖所展示的拖拽排序效果瞭。

<template>
  <div>
    <transition-group
      name="drag"
      class="list"
      tag="ul"
    >
      <li
        @dragenter="dragenter($event, index)"
        @dragover="dragover($event, index)"
        @dragstart="dragstart(index)"
        draggable
        v-for="(item, index) in list"
        :key="item.label"
        class="list-item">
        {{item.label}}
      </li>
    </transition-group>
  </div>
</template>
<script>
export default {
  data() {
    return {
      list: [
        { label: '列表1' },
        { label: '列表2' },
        { label: '列表3' },
        { label: '列表4' },
        { label: '列表5' },
        { label: '列表6' },
      ],
      dragIndex: '',
      enterIndex: '',
    };
  },
  methods: {
    shuffle() {
      this.list = this.$shuffle(this.list);
    },
    dragstart(index) {
      this.dragIndex = index;
    },
    dragenter(e, index) {
      e.preventDefault();
      // 避免源對象觸發自身的dragenter事件
      if (this.dragIndex !== index) {
        const moving = this.list[this.dragIndex];
        this.list.splice(this.dragIndex, 1);
        this.list.splice(index, 0, moving);
        // 排序變化後目標對象的索引變成源對象的索引
        this.dragIndex = index;
      }
    },
    dragover(e, index) {
      e.preventDefault();
    },
  },
};
</script>
<style lang="scss" scoped>
.list {
  list-style: none;
  .drag-move {
    transition: transform .3s;
  }
  .list-item {
    cursor: move;
    width: 300px;
    background: #EA6E59;
    border-radius: 4px;
    color: #FFF;
    margin-bottom: 6px;
    height: 50px;
    line-height: 50px;
    text-align: center;
  }
}
</style>

總結

到此這篇關於Vue實用功能之實現拖拽元素、列表拖拽排序的文章就介紹到這瞭,更多相關Vue列表拖拽排序內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: