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中封装axios并实现api接口的统一管理
Dec 25 Vue.js
如何使用RoughViz可视化Vue.js中的草绘图表
Jan 30 Vue.js
基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件功能
Feb 23 Vue.js
vue-router路由懒加载及实现的3种方式
Feb 28 Vue.js
vue如何批量引入组件、注册和使用详解
May 12 Vue.js
Vue Element UI自定义描述列表组件
May 18 Vue.js
vue2实现provide inject传递响应式
May 21 Vue.js
使用Vue3+Vant组件实现App搜索历史记录功能(示例代码)
Jun 09 Vue.js
一篇文章学会Vue中间件管道
Jun 20 Vue.js
vue报错function () { [native code] },无法出现我们想要的内容 Unknown custom element
Apr 11 Vue.js
使用vue判断当前环境是安卓还是IOS
Apr 12 Vue.js
vue3语法糖内的defineProps及defineEmits
Apr 14 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中的cookie不用刷新就生效的方法
2012/02/04 PHP
使用PHP遍历文件目录与清除目录中文件的实现详解
2013/06/24 PHP
php调用shell的方法
2014/11/05 PHP
php获取指定(访客)IP所有信息(地址、邮政编码、国家、经纬度等)的方法
2015/07/06 PHP
Jquery 高亮显示文本中重要的关键字
2009/12/24 Javascript
网页打开自动最大化的js代码
2012/08/22 Javascript
JS获取键盘上任意按键的值(实例代码)
2013/11/12 Javascript
JS简单实现文件上传实例代码(无需插件)
2013/11/15 Javascript
jquery动态改变form属性提交表单
2014/06/03 Javascript
深入理解requestAnimationFrame的动画循环
2016/09/20 Javascript
真正好用的js验证上传文件大小的简单方法
2016/10/27 Javascript
javascript事件的传播基础实例讲解(35)
2017/02/14 Javascript
JS html时钟制作代码分享
2017/03/03 Javascript
Vue学习笔记进阶篇之函数化组件解析
2017/07/21 Javascript
Angular中响应式表单的三种更新值方法详析
2017/08/22 Javascript
Vue引入jquery实现平滑滚动到指定位置
2018/05/09 jQuery
Vue 中文本内容超出规定行数后展开收起的处理的实现方法
2019/04/28 Javascript
微信小程序事件对象中e.target和e.currentTarget的区别详解
2019/05/08 Javascript
vue项目初始化到登录login页面的示例
2019/10/31 Javascript
微信小程序动态评分展示/五角星展示/半颗星展示/自定义长度展示功能的实现
2020/07/22 Javascript
[51:17]Mski vs VGJ.S Supermajor小组赛C组 BO3 第三场 6.3
2018/06/04 DOTA
Python代码解决RenderView窗口not found问题
2016/08/28 Python
Pandas DataFrame中的tuple元素遍历的实现
2019/10/23 Python
Django实现基于类的分页功能
2019/10/31 Python
python实现超级马里奥
2020/03/18 Python
HTML5之SVG 2D入门3—文本与图像及渲染文本介绍
2013/01/30 HTML / CSS
FitFlop澳大利亚官网:英国符合人体工学的鞋类品牌
2017/06/05 全球购物
瑞典廉价机票预订网站:Seat24
2018/06/19 全球购物
上海某公司.net方向笔试题
2014/09/14 面试题
如何利用cmp命令比较文件
2013/09/23 面试题
制作部班长职位说明书
2014/02/26 职场文书
员工生日活动方案
2014/08/24 职场文书
北京天坛导游词
2015/02/12 职场文书
标会主持词应该怎么写?
2019/08/15 职场文书
2019年励志签名:致拼搏路上的自己
2019/10/11 职场文书
详解redis分布式锁的这些坑
2021/05/19 Redis