antdesign-vue结合sortablejs实现两个table相互拖拽排序功能


Posted in Vue.js onJanuary 08, 2021

实现效果

本来想在网上看看有没有基于antdesign做的,然后发现是真的少啊!废话不多说,先上图:

antdesign-vue结合sortablejs实现两个table相互拖拽排序功能

sortablejs介绍

首先先来认识一下这个插件: sortablejs
大家可以去细读一下它的api文档:

antdesign-vue结合sortablejs实现两个table相互拖拽排序功能

这边我就着重介绍一下我用到的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: '.ant-table-row',
 animation: 150,
 group: { name: 'name', pull: true, put: true },
 onUpdate: function (evt) {
 
 },
 // 开始拖拽的时候
 onStart: function (evt) {
  
 },
 onAdd: function (evt) {
  
 },
 onRemove: function (evt) {
 
 }
 })
 },
 }

关于handle所取的class,因为我们是要对antdesign表格的每一行进行拖拽,所以要选取到他每一行的class。

antdesign-vue结合sortablejs实现两个table相互拖拽排序功能

至此两个table之间就可以实现拖拽效果,但仅仅只是拖拽效果
因为这样拖拽之后,两边的数据源并没有发生变化,而且明明已经拖拽过来之后,另一边的表格的展示页会存在错误:

antdesign-vue结合sortablejs实现两个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, 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)实现同一个表格上下拖拽排序

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 },
 //这里千万不要用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, 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
 },
 /**
 * 对数据排序并更新 table, 要求 o(oldIndex) 和 n(newIndex) 从 0开始
 */
 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方法来排序,不要用onEnd方法,因为只要你有拖拽效果,都会去触发onEnd方法,导致左右拖拽完后又会触发一次排序。

到此这篇关于antdesign-vue结合sortablejs实现两个table相互拖拽排序功能的文章就介绍到这了,更多相关antdesign-vue实现拖拽排序内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Vue.js 相关文章推荐
vue表单验证之禁止input输入框输入空格
Dec 03 Vue.js
基于Vue2实现移动端图片上传、压缩、拖拽排序、拖拽删除功能
Jan 05 Vue.js
Vue 集成 PDF.js 实现 PDF 预览和添加水印的步骤
Jan 22 Vue.js
vue中axios封装使用的完整教程
Mar 03 Vue.js
Vue3 Composition API的使用简介
Mar 29 Vue.js
如何用vue实现网页截图你知道吗
Nov 17 Vue.js
vue3使用vuedraggable实现拖拽功能
Apr 06 Vue.js
vue3.0 数字翻牌组件的使用方法详解
Apr 20 Vue.js
vue组件vue-esign实现电子签名
Apr 21 Vue.js
vue-treeselect的基本用法以及解决点击无法出现拉下菜单
Apr 30 Vue.js
vue实现在data里引入相对路径
Jun 05 Vue.js
vue本地构建热更新卡顿的问题“75 advanced module optimization”完美解决方案
Aug 05 Vue.js
vue-quill-editor插入图片路径太长问题解决方法
Jan 08 #Vue.js
vue编写简单的购物车功能
Jan 08 #Vue.js
解决vue使用vant轮播组件swipe + flex时文字抖动问题
Jan 07 #Vue.js
vuex的使用和简易实现
Jan 07 #Vue.js
vue watch监控对象的简单方法示例
Jan 07 #Vue.js
vue.js watch经常失效的场景与解决方案
Jan 07 #Vue.js
通过vue.extend实现消息提示弹框的方法记录
Jan 07 #Vue.js
You might like
PHP 高手之路(三)
2006/10/09 PHP
PHP中break及continue两个流程控制指令区别分析
2011/04/18 PHP
php三元运算符知识汇总
2015/07/02 PHP
大家都应该掌握的PHP关联数组使用技巧
2015/12/25 PHP
PHP实现的mysql主从数据库状态检测功能示例
2017/07/20 PHP
laravel获取不到session的三种解决办法【推荐】
2018/09/16 PHP
ExtJS扩展 垂直tabLayout实现代码
2009/06/21 Javascript
JavaScript 字符串与数组转换函数[不用split与join]
2009/12/13 Javascript
JS函数验证总结(方便js客户端输入验证)
2010/10/29 Javascript
关于JS控制代码暂停的实现方法分享
2012/10/11 Javascript
选择器中含有空格在使用示例及注意事项
2013/07/31 Javascript
js中substring和substr两者区别和使用方法
2015/11/09 Javascript
深入理解jQuery中的事件冒泡
2016/05/24 Javascript
jQuery实现底部浮动窗口效果
2016/09/07 Javascript
微信小程序搜索组件wxSearch实例详解
2017/06/08 Javascript
Vue.js2.0中的变化小结
2017/10/24 Javascript
[01:18]DOTA2超级联赛专访hanci ForLove淘汰感言曝光
2013/06/04 DOTA
python基于windows平台锁定键盘输入的方法
2015/03/05 Python
Python Requests安装与简单运用
2016/04/07 Python
遍历python字典几种方法总结(推荐)
2016/09/11 Python
Python文本相似性计算之编辑距离详解
2016/11/28 Python
Python标准库inspect的具体使用方法
2017/12/06 Python
python3判断url链接是否为404的方法
2018/08/10 Python
在OpenCV里使用特征匹配和单映射变换的代码详解
2019/10/23 Python
Pytorch中.new()的作用详解
2020/02/18 Python
django 解决扩展自带User表遇到的问题
2020/05/14 Python
使用纯 CSS 创作一个脉动 loader效果的源码
2018/09/28 HTML / CSS
沙特阿拉伯网上购物:Sayidaty Mall
2018/05/06 全球购物
美国豪华的多品牌精品店:The Webster
2019/07/31 全球购物
护士辞职信模板
2014/01/20 职场文书
高中毕业生登记表自我鉴定范文
2014/03/18 职场文书
竞选卫生委员演讲稿
2014/04/28 职场文书
计算机系本科生求职信
2014/05/31 职场文书
2016年大学自主招生自荐信范文
2015/03/24 职场文书
庆祝教师节主题班会
2015/08/17 职场文书
用 Python 定义 Schema 并生成 Parquet 文件详情
2021/09/25 Python