antdesign-vue結(jié)合sortablejs實(shí)現(xiàn)兩個(gè)table相互拖拽排序功能
實(shí)現(xiàn)效果
本來(lái)想在網(wǎng)上看看有沒(méi)有基于antdesign做的,然后發(fā)現(xiàn)是真的少啊!廢話不多說(shuō),先上圖:

sortablejs介紹
首先先來(lái)認(rèn)識(shí)一下這個(gè)插件: sortablejs
大家可以去細(xì)讀一下它的api文檔:

這邊我就著重介紹一下我用到的api。
1.group可以傳入對(duì)象,參數(shù)值為name,pull,put,
name:如果是要兩個(gè)列表下進(jìn)行拖動(dòng)的話,name的值必須為一樣;
pull:pull用來(lái)定義從這個(gè)列表容器移動(dòng)出去的設(shè)置,true/false/‘clone'/function
- true :列表容器內(nèi)的列表單元可以被移出;
- false:列表容器內(nèi)的列表單元不可以被移出;
- clone:列表單元移出,移動(dòng)的為該元素的副本;
- function:用來(lái)進(jìn)行pull的函數(shù)判斷,可以進(jìn)行復(fù)雜邏輯,在函數(shù)中return false/true來(lái)判斷是否移出;
put:put用來(lái)定義往這個(gè)列表容器放置列表單元的的設(shè)置,true/false/[‘foo',‘bar']/function;
- true:列表容器可以從其他列表容器內(nèi)放入列表單元;
- false:與true相反;
- [‘foo',‘bar']:這個(gè)可以是一個(gè)字符串或者是字符串的數(shù)組,代表的是group配置項(xiàng)里定義的name值;
- function:用來(lái)進(jìn)行put的函數(shù)判斷,可以進(jìn)行復(fù)雜邏輯,在函數(shù)中return false/true來(lái)判斷是否放入;
2.animation ms, number 單位:ms,定義排序動(dòng)畫(huà)的時(shí)間;
3. handle: 格式為簡(jiǎn)單css選擇器的字符串,使列表單元中符合選擇器的元素成為拖動(dòng)的手柄,只有按住拖動(dòng)手柄才能使列表單元進(jìn)行拖動(dòng)(你想讓哪個(gè)元素拖動(dòng)就綁定這個(gè)元素的class);
4. onStart:function(evt){}開(kāi)始拖拽的回調(diào)方法;
5. onUpdate:function(evt){}列表內(nèi)元素順序更新的回調(diào)方法;
6. onAdd:function(evt){}元素從一個(gè)列表拖拽到另一個(gè)列表的回調(diào)方法;
7. onRemove:function(evt){} 元素從列表中移除進(jìn)入另一個(gè)列表的回調(diào)方法;
這個(gè)需求用到這些api也就足夠了。
具體實(shí)現(xiàn)
1.第一步先初始化sortable方法,因?yàn)槲覀兊男枨笫莾蓚€(gè)表格拖拽,所以初始化2個(gè)方法。
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 實(shí)現(xiàn)拖動(dòng)
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) {
},
// 開(kāi)始拖拽的時(shí)候
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: '.ant-table-row',
animation: 150,
group: { name: 'name', pull: true, put: true },
onUpdate: function (evt) {
},
// 開(kāi)始拖拽的時(shí)候
onStart: function (evt) {
},
onAdd: function (evt) {
},
onRemove: function (evt) {
}
})
},
}
關(guān)于handle所取的class,因?yàn)槲覀兪且獙?duì)antdesign表格的每一行進(jìn)行拖拽,所以要選取到他每一行的class。

至此兩個(gè)table之間就可以實(shí)現(xiàn)拖拽效果,但僅僅只是拖拽效果。
因?yàn)檫@樣拖拽之后,兩邊的數(shù)據(jù)源并沒(méi)有發(fā)生變化,而且明明已經(jīng)拖拽過(guò)來(lái)之后,另一邊的表格的展示頁(yè)會(huì)存在錯(cuò)誤:

排序是我右邊表格特有的,但是這邊的表格是不需要這個(gè)排序的,而且如果拖拽成功的話為什么還會(huì)顯示暫無(wú)數(shù)據(jù)呢,最后左邊表頭的CheckBox也無(wú)法選中。所以到此為止只是有拖拽效果而已。
2.在拖拽動(dòng)作之后,把左右兩邊的數(shù)據(jù)源重新賦值,這里有兩種實(shí)現(xiàn)思路:
- 每一次拖拽之后都去請(qǐng)求后臺(tái)數(shù)據(jù),拿到新的數(shù)據(jù)源之后重新賦值給表格,
- 前端自己做好數(shù)據(jù)源的處理,等所有的拖拽結(jié)束之后排好序再給后臺(tái)保存。
考慮到性能消耗,我就選擇了第二種:
1)定義左右兩邊的數(shù)據(jù)源數(shù)組
data(){
return{
unMatchedList: [], // 左邊未匹配的數(shù)據(jù)
dataList: [], // 右邊已匹配的數(shù)據(jù)
pullIndex :'',//原數(shù)組拖拽元素的下標(biāo)
}
}
2)在每一次remove或者add的時(shí)候更新數(shù)據(jù)源,這里只寫(xiě)了一個(gè)表格拖拽的方法,另一個(gè)只要把that.dataList和that.unMatchedList左右兩邊的數(shù)據(jù)源賦值調(diào)換一下就行,就不貼重復(fù)代碼了
// 開(kāi)始拖拽的時(shí)候
onStart: function (evt) {
that.pullIndex = evt.oldIndex
},
onAdd: function (evt) {
//evt.newIndex 移入到新數(shù)組的下標(biāo)
//pullIndex 原數(shù)組拖拽元素的下標(biāo)
that.dataList.splice(evt.newIndex, 0, 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)實(shí)現(xiàn)同一個(gè)表格上下拖拽排序
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 },
//這里千萬(wàn)不要用onEnd 方法
onUpdate: function (evt) {
var o = evt.oldIndex
var n = evt.newIndex
if (o === n) {
return
}
that.sortListAndUpdate(that.dataList, o, n)
},
})
},
// 對(duì)數(shù)據(jù)進(jìn)行排序,要求 o(oldIndex) 和 n(newIndex) 從 0開(kāi)始
sortList (list, o, n) {
var newTableData = JSON.parse(JSON.stringify(list))
var data = newTableData.splice(o, 1, null)
newTableData.splice(o < n ? n + 1 : n, 0, data[0])
newTableData.splice(o > n ? o + 1 : o, 1)
return newTableData
},
/**
* 對(duì)數(shù)據(jù)排序并更新 table, 要求 o(oldIndex) 和 n(newIndex) 從 0開(kāi)始
*/
sortListAndUpdate (list, o, n) {
var newTableData = this.sortList(list, o, n)
newTableData.forEach((item, index) => {
item.sort = index + 1
})
this.$nextTick(() => {
this.dataList = newTableData
that.$refs.table2 && this.$refs.table2.refresh(true)
})
},
這邊我們選用onUpdate方法來(lái)排序,不要用onEnd方法,因?yàn)橹灰阌型献Ч?,都?huì)去觸發(fā)onEnd方法,導(dǎo)致左右拖拽完后又會(huì)觸發(fā)一次排序。
到此這篇關(guān)于antdesign-vue結(jié)合sortablejs實(shí)現(xiàn)兩個(gè)table相互拖拽排序功能的文章就介紹到這了,更多相關(guān)antdesign-vue實(shí)現(xiàn)拖拽排序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue-resourse將json數(shù)據(jù)輸出實(shí)例
這篇文章主要為大家詳細(xì)介紹了vue-resourse將json數(shù)據(jù)輸出實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
Vue Render函數(shù)創(chuàng)建DOM節(jié)點(diǎn)代碼實(shí)例
這篇文章主要介紹了Vue Render函數(shù)創(chuàng)建DOM節(jié)點(diǎn)代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
基于Vue uniapp實(shí)現(xiàn)貪吃蛇游戲
貪吃蛇游戲想必是很多70、80后的回憶,一直到現(xiàn)在也深受大家的喜歡。本文將利用Vue+uniapp實(shí)現(xiàn)這一經(jīng)典的游戲,感興趣的可以了解一下2022-04-04
vue?cli?局部混入mixin和全局混入mixin的過(guò)程
這篇文章主要介紹了vue?cli?局部混入mixin和全局混入mixin的過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
vue+iview實(shí)現(xiàn)手機(jī)號(hào)分段輸入框
這篇文章主要為大家詳細(xì)介紹了vue+iview實(shí)現(xiàn)手機(jī)號(hào)分段輸入框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
vue3使用Element-plus的el-pagination分頁(yè)組件時(shí)無(wú)法顯示中文
本文主要介紹了vue3使用Element-plus的el-pagination分頁(yè)組件時(shí)無(wú)法顯示中文,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-12-12
vue.js移動(dòng)端tab組件的封裝實(shí)踐實(shí)例
本篇文章主要介紹了vue.js移動(dòng)端tab的封裝實(shí)踐實(shí)例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06
Vue3搭建組件庫(kù)開(kāi)發(fā)環(huán)境的示例詳解
這篇文章給大家分享Vue3搭建組件庫(kù)開(kāi)發(fā)環(huán)境,給大家講解依次搭建組件庫(kù)、example、文檔、cli,本文內(nèi)容是搭建組件庫(kù)的開(kāi)發(fā)環(huán)境的過(guò)程,感興趣的朋友跟隨小編一起看看吧2022-11-11
使用vue-draggable-plus實(shí)現(xiàn)拖拽排序
最近遇到一個(gè)需求,在 Vue3 的一個(gè) H5 頁(yè)面當(dāng)中點(diǎn)擊拖拽圖標(biāo)上下拖動(dòng) tab 子項(xiàng),然后點(diǎn)擊保存可以保存最新的 tab 項(xiàng)順序,同事說(shuō)可以用 vue-draggable-plus 這個(gè)庫(kù)來(lái)實(shí)現(xiàn)拖拽,所以本文給大家介紹了如何使用vue-draggable-plus實(shí)現(xiàn)拖拽排序,需要的朋友可以參考下2024-01-01

