1. 程式人生 > 程式設計 >antdesign-vue結合sortablejs實現兩個table相互拖拽排序功能

antdesign-vue結合sortablejs實現兩個table相互拖拽排序功能

實現效果

本來想在網上看看有沒有基於antdesign做的,然後發現是真的少啊!廢話不多說,先上圖:

在這裡插入圖片描述

sortablejs介紹

首先先來認識一下這個外掛: sortablejs
大家可以去細讀一下它的api文件:

在這裡插入圖片描述

這邊我就著重介紹一下我用到的api。
1.group可以傳入物件,引數值為name,pull,put,
name:如果是要兩個列表下進行拖動的話,name的值必須為一樣;
pull:pull用來定義從這個列表容器移動出去的設定,true/false/‘clone'/function

  • true :列表容器內的列表單元可以被移出;
  • false:列表容器內的列表單元不可以被移出;
  • clone:列表單元移出,移動的為該元素的副本;
  • function:用來進行pull的函式判斷,可以進行復雜邏輯,在函式中return false/true來判斷是否移出;

put:put用來定義往這個列表容器放置列表單元的的設定,true/false/[‘foo',‘bar']/function;

  • true:列表容器可以從其他列表容器內放入列表單元;
  • false:與true相反;
  • [‘foo',‘bar']:這個可以是一個字串或者是字串的陣列,代表的是group配置項裡定義的name值;
  • function:用來進行put的函式判斷,可以進行復雜邏輯,在函式中return false/true來判斷是否放入;

2.animation

ms,number 單位:ms,定義排序動畫的時間;
3. handle: 格式為簡單css選擇器的字串,使列表單元中符合選擇器的元素成為拖動的手柄,只有按住拖動手柄才能使列表單元進行拖動(你想讓哪個元素拖動就繫結這個元素的class);
4. onStart:function(evt){}開始拖拽的回撥方法;
5. onUpdate:function(evt){}列表內元素順序更新的回撥方法;
6. onAdd:function(evt){}元素從一個列表拖拽到另一個列表的回撥方法;
7. onRemove:function(evt){} 元素從列表中移除進入另一個列表的回撥方法;
這個需求用到這些
api也就足夠了。

具體實現

1.第一步先初始化sortable方法,因為我們的需求是兩個表格拖拽,所以初始化2個方法。
html程式碼

<s-table
 ref="table"
 size="default"
 class="left-table"
 rowKey="key"
 :columns="columns"
 :data="loadData">
</s-table>
  
<s-table
 class="sort-table"
 ref="table2"
 size="default"
 class="left-table"
 rowKey="key"
 :columns="columns"
 :data="loadData">
</s-table>

具體的columns 和loadData就不多餘闡述。

JS程式碼

import Sortable from 'sortablejs'
methods:{
 // 初始化 sortable 實現拖動
 initSortable () {
 var that = this
 var el = this.$el.querySelector('.sort-table tbody')
 Sortable.create(el,{
 handle: '.ant-table-row',animation: 150,group: { name: 'name',pull: true,put: true },onUpdate: function (evt) {
 
 },// 開始拖拽的時候
 onStart: function (evt) {
  
 },onAdd: function (evt) {
  
 },onRemove: function (evt) {
 
 }
 })
 },initSortable1 () {
 var that = this
 var el = this.$el.querySelector('.left-table tbody')
 Sortable.create(el,}

關於handle所取的class,因為我們是要對antdesign表格的每一行進行拖拽,所以要選取到他每一行的class。

在這裡插入圖片描述

至此兩個table之間就可以實現拖拽效果,但僅僅只是拖拽效果
因為這樣拖拽之後,兩邊的資料來源並沒有發生變化,而且明明已經拖拽過來之後,另一邊的表格的展示頁會存在錯誤:

在這裡插入圖片描述

排序是我右邊表格特有的,但是這邊的表格是不需要這個排序的,而且如果拖拽成功的話為什麼還會顯示暫無資料呢,最後左邊表頭的CheckBox也無法選中。所以到此為止只是有拖拽效果而已。
2.在拖拽動作之後,把左右兩邊的資料來源重新賦值,這裡有兩種實現思路:

  • 每一次拖拽之後都去請求後臺資料,拿到新的資料來源之後重新賦值給表格,
  • 前端自己做好資料來源的處理,等所有的拖拽結束之後排好序再給後臺儲存。

考慮到效能消耗,我就選擇了第二種:
1)定義左右兩邊的資料來源陣列

data(){
 return{
 unMatchedList: [],// 左邊未匹配的資料
 dataList: [],// 右邊已匹配的資料
 pullIndex :'',//原陣列拖拽元素的下標
 }
}

2)在每一次remove或者add的時候更新資料來源,這裡只寫了一個表格拖拽的方法,另一個只要把that.dataListthat.unMatchedList左右兩邊的資料來源賦值調換一下就行,就不貼重複程式碼了

 // 開始拖拽的時候
 onStart: function (evt) {
  that.pullIndex = evt.oldIndex
 },onAdd: function (evt) {
 //evt.newIndex 移入到新陣列的下標
 //pullIndex 原陣列拖拽元素的下標
  that.dataList.splice(evt.newIndex,that.unMatchedList[that.pullIndex])
  that.dataList.forEach((item,index) => {
  item.sort = index + 1
  })
  //通知table檢視更新
  that.$nextTick(() => {
  that.$refs.table2 && this.$refs.table2.refresh(true)
 		 that.$refs.table && this.$refs.table.refresh(true)
  })
 },onRemove: function (evt) {
  that.dataList.splice(evt.oldIndex,1)
  that.dataList.forEach((item,index) => {
  item.sort = index + 1
  })
  that.$nextTick(() => {
  that.$refs.table2 && this.$refs.table2.refresh(true)
 		that.$refs.table && this.$refs.table.refresh(true)
  })
 }
 })

3)實現同一個表格上下拖拽排序

initSortable () {
 var that = this
 var el = this.$el.querySelector('.sort-table tbody')
 Sortable.create(el,//這裡千萬不要用onEnd 方法
 onUpdate: function (evt) {
  var o = evt.oldIndex
  var n = evt.newIndex
  if (o === n) {
  return
  }
  that.sortListAndUpdate(that.dataList,o,n)
 },})
 },// 對資料進行排序,要求 o(oldIndex) 和 n(newIndex) 從 0開始
 sortList (list,n) {
 var newTableData = JSON.parse(JSON.stringify(list))
 var data = newTableData.splice(o,1,null)
 newTableData.splice(o < n ? n + 1 : n,data[0])
 newTableData.splice(o > n ? o + 1 : o,1)
 return newTableData
 },/**
 * 對資料排序並更新 table, 要求 o(oldIndex) 和 n(newIndex) 從 0開始
 */
 sortListAndUpdate (list,n) {
 var newTableData = this.sortList(list,n)
 newTableData.forEach((item,index) => {
 item.sort = index + 1
 })
 this.$nextTick(() => {
 this.dataList = newTableData
 that.$refs.table2 && this.$refs.table2.refresh(true)
 })
 },

這邊我們選用onUpdate方法來排序,不要用onEnd方法,因為只要你有拖拽效果,都會去觸發onEnd方法,導致左右拖拽完後又會觸發一次排序。

到此這篇關於antdesign-vue結合sortablejs實現兩個table相互拖拽排序功能的文章就介紹到這了,更多相關antdesign-vue實現拖拽排序內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!