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 相关文章推荐
快速解决vue2+vue-cli3项目ie兼容的问题
Nov 17 Vue.js
详解vue中使用transition和animation的实例代码
Dec 12 Vue.js
vue 导航守卫和axios拦截器有哪些区别
Dec 19 Vue.js
Vue实现小购物车功能
Dec 21 Vue.js
Vue组件简易模拟实现购物车
Dec 21 Vue.js
vue监听键盘事件的相关总结
Jan 29 Vue.js
vue实现拖拽进度条
Mar 01 Vue.js
Vue通过懒加载提升页面响应速度
May 10 Vue.js
Vue Element-ui表单校验规则实现
Jul 09 Vue.js
vue整合百度地图显示指定地点信息
Apr 06 Vue.js
vue实现可以快进后退的跑马灯组件
Apr 08 Vue.js
vue数据字典取键值项目的字典问题
Apr 12 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类的使用 实例代码讲解
2009/12/28 PHP
Docker 如何布置PHP开发环境
2016/06/21 PHP
用php+ajax新建流程(请假、进货、出货等)
2017/06/11 PHP
PHP实现批量重命名某个文件夹下所有文件的方法
2017/09/04 PHP
该如何加载google-analytics(或其他第三方)的JS
2010/05/13 Javascript
使用jquery的ajax需要注意的地方dataType的设置
2013/08/12 Javascript
判断js中各种数据的类型方法之typeof与0bject.prototype.toString讲解
2013/11/07 Javascript
javascript原型模式用法实例详解
2015/06/04 Javascript
微信小程序 PHP后端form表单提交实例详解
2017/01/12 Javascript
jQuery.parseJSON()函数详解
2019/02/28 jQuery
[40:16]TFT vs Mski Supermajor小组赛C组 BO3 第二场 6.3
2018/06/04 DOTA
python写日志封装类实例
2015/06/28 Python
Python获取系统所有进程PID及进程名称的方法示例
2018/05/24 Python
numpy 对矩阵中Nan的处理:采用平均值的方法
2018/10/30 Python
python命令行工具Click快速掌握
2019/07/04 Python
python使用yield压平嵌套字典的超简单方法
2019/11/02 Python
Python 内置函数globals()和locals()对比详解
2019/12/23 Python
tensorflow查看ckpt各节点名称实例
2020/01/21 Python
python爬虫开发之selenium模块详细使用方法与实例全解
2020/03/09 Python
python变量的作用域是什么
2020/05/26 Python
python自动化测试三部曲之unittest框架的实现
2020/10/07 Python
如何Tkinter模块编写Python图形界面
2020/10/14 Python
CSS3制作酷炫的条纹背景
2017/11/09 HTML / CSS
详解CSS3媒体查询响应式布局bootstrap 框架原理实战(推荐)
2020/11/16 HTML / CSS
利用html5的websocket实现websocket聊天室
2013/12/12 HTML / CSS
挪威手表购物网站:Klokker
2016/09/19 全球购物
康拓普公司Java笔面试
2016/09/23 面试题
Discard Protocol抛弃协议的作用是什么
2015/10/10 面试题
应届生会计求职信
2013/11/11 职场文书
英语专业职业生涯规划范文
2014/03/05 职场文书
大队干部竞选演讲稿
2014/04/28 职场文书
心理咨询承诺书
2014/05/20 职场文书
2014年政协委员工作总结
2014/12/01 职场文书
离开雷锋的日子观后感
2015/06/09 职场文书
Ubuntu Server 安装Tomcat并配置systemctl
2022/04/28 Servers
Java8 CompletableFuture 异步回调
2022/04/28 Java/Android