Vue 结合Sortablejs实现table行排序
场景
在一个列表展示页面上,使用了表格组件,原有组件本身不支持拖拽功能,需求要求在列表的基础上支持行拖拽排序。因此引入了Sortablejs插件。
问题及解决方案
引入Sortablejs后刚开始都很顺利,效果的拖拽基本功能效果已实现。代码如下
const tbody = this.$refs.Scheduling.querySelectorAll('.ant-table-tbody') // 元素选择器名称根据实际内容替换
Sortable.create(tbody[0]) //具体Sortablejs的api文档可查看官网
下一步就是保存数据
但是在保存数据的时候才发现,数据并没有修改,还是原来的数据,接下来就来处理数据排序的问题,经查看Sortablejs文档引入了onEnd方法,也可用onUpdate方法
代码修改如下
const tbody = this.$refs.Scheduling.querySelectorAll('.ant-table-tbody') // 元素选择器名称根据实际内容替换
const _this = this
Sortable.create(tbody[0], {
onEnd({ newIndex, oldIndex }) {
const currRow = _this.databases.splice(oldIndex, 1)[0]
_this.databases.splice(newIndex, 0, currRow)
}
})
修改完之后本以为可以了,就去调试一下,就出现了比较诡异的问题。A和B拖拽交换位置之后,B和A又神奇的换回去了,整体都乱套了!很奇怪。
经查看资料才发现
Vue的实现原理,在Vue2.0之前是通过defineProperty依赖注入和跟踪的方式实现双向绑定。针对v-for数组指令,如果指定了唯一的Key,则会通过高效的Diff算法计算出数组内元素的差异,进行最少的移动或删除操作。而Vue2.0之后在引入了Virtual Dom之后,Children元素的Dom Diff算法和前者其实是相似的,唯一的区别就是,2.0之前Diff直接针对v-for指令的数组对象,2.0之后则针对Virtual Dom。DOM Diff算法在这里不再赘述,这里解释的比较清楚virtual-dom diff算法
假设我们的列表元素数组是[‘A','B','C','D']
渲染出来后的DOM节点是[$A,$B,$C,$D]
那么Virtual Dom对应的结构就是[{elm:$A,data:'A'},
{elm:$B,data:'B'},
{elm:$C,data:'C'},
{elm:$D,data:'D'}]
假设拖拽排序之后,真实的DOM变为[$B,$A,$C,$D]
此时我们只操作了真实DOM,改编了它的位置,而Virtual Dom的结构并没有改变,依然是[{elm:$A,data:'A'},
{elm:$B,data:'B'},
{elm:$C,data:'C'},
{elm:$D,data:'D'}]
此时我们把列表元素也按照真实DOM排序后变成[‘B','A','C','D']
这时候根据Diff算法,计算出的Patch为,VNode前两项是同类型的节点,所以直接更新,即把$A节点更新成$B,把$B节点更新成$A,真实DOM又变回了[$A,$B,$C,$D]
所以就出现了拖拽之后又被Patch算法更新了一次的问题,操作路径可以简单理解为
拖拽移动真实DOM -> 操作数据数组 -> Patch算法再更新真实DOM
根本原因
根本原因是Virtual DOM和真实DOM之间出现了不一致。
所以在Vue2.0以前,因为没有引入Virtual DOM,这个问题是不存在的。
在使用Vue框架的时候要尽量避免直接操作DOM
最后修改代码如下
onEnd({ newIndex, oldIndex }) {
const currRowdom = tbody[0].children[newIndex]
const oldRowdom = tbody[0].children[oldIndex]
tbody[0].removeChild(currRowdom)
if (newIndex > oldIndex) {
tbody[0].insertBefore(currRowdom, oldRowdom)
} else {
tbody[0].insertBefore(currRowdom, oldRowdom.nextSibling)
}
const currRow = _this.databases.splice(oldIndex, 1)[0]
_this.databases.splice(newIndex, 0, currRow)
}
Vue 结合Sortablejs实现table行排序的更多相关文章
- VUE +element el-table运用sortable 拖拽table排序,实现行排序,列排序
Sortable.js是一款轻量级的拖放排序列表的js插件(虽然体积小,但是功能很强大) 项目需求是要求能对element中 的table进行拖拽行排序 这里用到了sorttable Sortable ...
- Vue. 之 Element获取table中选中的行
Vue. 之 Element获取table中选中的行 问题描述: 如下截图,在Table中选择数据后,然后在点击“统计”按钮,获取Table表中选择的行 解决方案: 1. 给“统计”这个按钮添加一个点 ...
- JavaScript Table行定位效果
作者:cloudgamer 时间: 2009-09-17 文档类型:原创 来自:蓝色理想 第 1 页 JavaScript Table行定位效果 [1] 第 2 页 JavaScript Table行 ...
- Javascript实现表格行排序
网站开发中凡是用到表格来展示数据的,往往都要根据某个列来对行排序,下面是我从书上看到的一个行排序例子,看过后受益匪浅,故分享出来. 直接献上完整代码: <!doctype html> &l ...
- 循序渐进VUE+Element 前端应用开发(30)--- ABP后端和Vue+Element前端结合的分页排序处理
在很多列表展示数据的场合中,大多数都会需要一个排序的处理,以方便快速查找排序所需的数据,本篇随笔介绍如何结合ABP后端和Vue+Element前端结合的分页排序处理过程. 1.Vue+Element前 ...
- asp.net实现动态添加table行
asp.net动态的生成,删除table的行,主要是在后台动态创建单元行,单元表格,效果图: 2.代码: <%@ Page Language="C#" AutoEventWi ...
- jquery 获得table 行数
1.获得Table总行数,分别使用了两种方法,结果不同:: 1).$("#table_Id").children("tr").length; 只能获得静态页面t ...
- table行转列
table行转列 摘要 在使用ews调用exhange的收件箱的并在h5页面显示邮件详情的时候,因为返回的每封邮件的内容都是htmlbody,没有textbody.每封邮件又没什么规律,用正则表达式来 ...
- Datatable根据多行排序
DataTable dt = new DataTable(); dt.Columns.Add("ID", typeof(int)); dt.Columns.Add("Na ...
- Lua table.sort排序
在用table.sort 排序的时候注意,如果使用多个条件排序,应在一个排序函数里按照条件优先级进行比较排序. 例如 local t = { {time = , i = }, {time = , i ...
随机推荐
- 深入理解Hadoop读书笔记-3
背景 公司的物流业务系统目前实现了使用storm集群进行过门事件的实时计算处理,但是还有一个需求,我们需要存储每个标签上传的每条明细数据,然后进行定期的标签报表统计,这个是目前的实时计算框架无法满足的 ...
- php文件和文件夹操作类
文件和文件夹操作 移动 | 复制 | 删除 | 重命名 | 下载 <?php namespace Framework\Tools; use PharData; class FileManager ...
- 线性判别分析(LDA):降维与分类的完美结合
在机器学习领域,线性判别分析(Linear Discriminant Analysis,简称LDA)是一种经典的算法,它在降维和分类任务中都表现出色. LDA通过寻找特征空间中能够最大化类间方差和最小 ...
- c数组与结构体
数组,存储同类型的复合类型:结构体,存储不同类型的复合类型,用于自定义数据结构. 计算机中,针对存储大量数据的集合,有着两种方式,一种是以块式集中存储数据,这就是数组的存储方式,大量同类型的数据集中放 ...
- ipconfig出现媒体状态为媒体已断开连接问题
1.可能是因为路由器或者是交换机没有DHCP功能,需要手动的给电脑配置IP和掩码
- eolinker请求参数:提交参数JSON转换格式不正确的解决方法
当某个接口的提交参数类型为"array"时,该接口被自动化测试调用会转换成text类型. 导致执行测试的时候,整个参数转化json格式不正确 解决方法是在 格式不正确的项后面 配 ...
- 工具 | Hacking
0x00 简介 Hacking是一款包含多种渗透测试功能的脚本. 下载地址: Hacking下载:Hacking下载 0x01 功能说明 Brute Force DDos Attack NMap Po ...
- 操作系统综合题之“请填写信号量值并说明操作结果(正常、阻塞或唤醒。如阻塞或者唤醒,需说明阻塞或者被唤醒的是P1还是P2)(信号量操作流程-代码补充)”
1.问题:题36表是两个同步进程的模拟执行,生产者将物品放入共享缓冲区供消费者使用,缓冲区可放2件物品,使用2个信号量,并置初值为S1 = 2,S2=0.现已知操作情况,请填写信号量值并说明操作结果( ...
- 卢卡斯(lucas)定理
对于质数 \(p\),有 \[{\Large \begin{aligned} & \binom{n}{m} \equiv \binom{\left \lfloor n/p \right \rf ...
- storageclass和本地持久化存储
StorageClass 之前我们部署了PV 和 PVC 的使用方法,但是前面的 PV 都是静态的,什么意思?就是我要使用的一个 PVC 的话就必须手动去创建一个 PV,我们也说过这种方式在很大程度上 ...