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 相关文章推荐
springboot+vue实现文件上传下载
Nov 17 Vue.js
vue 使用 sortable 实现 el-table 拖拽排序功能
Dec 26 Vue.js
基于vuex实现购物车功能
Jan 10 Vue.js
vue element el-transfer增加拖拽功能
Jan 15 Vue.js
基于vue的video播放器的实现示例
Feb 19 Vue.js
Vue.js 带下拉选项的输入框(Textbox with Dropdown)组件
Apr 17 Vue.js
vue中div禁止点击事件的实现
Apr 02 Vue.js
VUE使用draggable实现组件拖拽
Apr 06 Vue.js
vue使用watch监听属性变化
Apr 30 Vue.js
Vue Mint UI mt-swipe的使用方式
Jun 05 Vue.js
Vue2项目中对百度地图的封装使用详解
Jun 16 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
Windows中使用计划任务自动执行PHP程序实例
2014/05/09 PHP
ThinkPHP3.1之D方法实例详解
2014/06/20 PHP
PHP给前端返回一个JSON对象的实例讲解
2018/05/31 PHP
js 图片随机不定向浮动的实现代码
2013/07/02 Javascript
js固定DIV高度,超出部分自动添加滚动条的简单方法
2013/07/10 Javascript
js中一个函数获取另一个函数返回值问题探讨
2013/11/21 Javascript
createTextRange()的使用示例含文本框选中部分文字内容
2014/02/24 Javascript
浅谈被jQuery抛弃的函数及替代函数
2015/05/03 Javascript
JS实现的5级联动Select下拉选择框实例
2015/08/17 Javascript
JS实现可自定义大小,可双击关闭的弹出层效果
2015/10/16 Javascript
基于JavaScript短信验证码如何实现
2016/01/24 Javascript
JavaScript小技巧整理篇(非常全)
2016/01/26 Javascript
Javascript操作dom对象之select全面解析
2017/04/24 Javascript
JavaScript中in和hasOwnProperty区别详解
2017/08/04 Javascript
微信小程序实现简单评论功能
2018/11/28 Javascript
构建大型 Vue.js 项目的10条建议(小结)
2019/11/14 Javascript
Vuex实现简单购物车
2021/01/10 Vue.js
用Python实现命令行闹钟脚本实例
2016/09/05 Python
PYTHON 中使用 GLOBAL引发的一系列问题
2016/10/12 Python
更换Django默认的模板引擎为jinja2的实现方法
2018/05/28 Python
基于Python中求和函数sum的用法详解
2018/06/28 Python
NLTK 3.2.4 环境搭建教程
2018/09/19 Python
win7 x64系统中安装Scrapy的方法
2018/11/18 Python
python利用Opencv实现人脸识别功能
2019/04/25 Python
Django接收post前端返回的json格式数据代码实现
2019/07/31 Python
Python模块的制作方法实例分析
2019/12/21 Python
如何利用python发送邮件
2020/09/26 Python
8款精美的CSS3表单设计(登录表单/下拉选择/按钮附演示及源码)
2013/02/04 HTML / CSS
美国领先的眼镜和太阳镜在线零售商:Glasses.com
2019/08/26 全球购物
工程项目经理岗位职责
2013/12/15 职场文书
制药工程专业个人求职自荐信
2014/01/25 职场文书
园林设计专业毕业生求职信
2014/03/23 职场文书
婚礼秀策划方案
2014/05/19 职场文书
计生工作先进事迹
2014/08/15 职场文书
Python实现socket库网络通信套接字
2021/06/04 Python
MySql中的json_extract函数处理json字段详情
2022/06/05 MySQL