当前位置: 首页 > news >正文

vxe-table和sortablejs实现行拖动

目的:

在table中实现行拖动排序功能。

问题1:

在使用Sortable对table创建可拖拽排序功能的时候,我们给每一行都锚定了一个可以拖动的图标,上边绑定了一个class,只有拖动这个图标才能拖动整行进行排序。

但是我给table创建拖拽排序功能后,进行拖拽实验,结果不能用。

这是因为在获取tableDOM元素的时候出现了问题。

initSortable () {const tableSort = this.$refs.table// 另外一种获取方法const array = tableSort.$el.querySelectorAll('.vxe-table--body tbody')for (let i = 0; i < array.length; i++) {Sortable.create(array[i], {handle: '.btn_sort',animation: 150,draggable: '.vxe-body--row',onEnd: ({ newIndex, oldIndex }) => {const singleList = this.form.item_listconst item = singleList.splice(oldIndex, 1)[0]singleList.splice(newIndex, 0, item)this.form.item_list = []this.$nextTick(() => {this.form.item_list = [...singleList]})}})}// 所有tbody},

使用的元素js方法querySelectorAll,来获取tbody,这个方法只在获取时"拍一张快照",之后即使 DOM 改变也不会更新。

在table渲染的时候是先渲染出来主体tbody的,而左右两侧固定列是后渲染出来的。

而我们使用querySelectorAll获取DOM的时候,它所拍下的快照只有主体tbody,没有左右两侧固定列的tbody。这就造成如果我用来拖动的图标是固定列,那就没法找到对应的DOM元素,Sortable也创建不了拖动方法了。

那就有人想到使用nextTick,在下次渲染后再来获取DOM了,这个方法我也用了,但是还是不行,还是获取不到固定列的DOM元素。原因应该还是这固定列的渲染时机不再这次渲染事件中,具体原因没去寻找。

那既然js原生获取DOM的方法有获取静态DOM的方法,那也有获取实时DOM的方法。

是的。有些 DOM 获取方法返回的是实时更新的集合(动态) ,而有些返回的是静态快照(静态)

DOM 元素获取方法总览

方法

返回类型

是否动态更新

常用性

说明

getElementById()

Element

⭐⭐⭐⭐

根据 id 获取单个元素

getElementsByTagName()

HTMLCollection

⭐⭐⭐

按标签名获取多个元素

getElementsByClassName()

HTMLCollection

⭐⭐⭐⭐

按类名获取多个元素

getElementsByName()

NodeList(动态)

⭐⭐

按 name 属性获取表单项

querySelector()

Element

⭐⭐⭐⭐⭐

返回第一个匹配的元素

querySelectorAll()

NodeList(静态)

⭐⭐⭐⭐⭐

返回所有匹配的元素(不会自动更新)

这里我为了解决这个问题又实用了getElementsByTagName方法,确实是获取到了固定列的tbodyDOM。

但是这里需要注意一点。HTMLCollection和NodeList的区别。

特性

HTMLCollection

NodeList

实时性

实时更新(live)

大部分静态(除了 childNodes

方法

只有 length 和索引访问

有 forEach 等方法

内容

只包含 Element 节点

包含所有节点类型

直接获取的HTMLCollection是不能直接使用的,需要转为数组才能遍历使用上面的方法。

但是转为数组后,问题又来了,转为数组后只有一个主题tbody了。还是因为方法执行时只有主体tbody,后面的两个固定列tbody是后面加进来的。

至于getElementsByName这个直接获取NodeList的方法是需要name参数的,而vxe-table渲染出来的table是没有name属性的,所以不能用,至于先用getElementsByTagName给他们增加个name再使用getElementsByName这个方法也试了,行不通。

解决方案:

至于解决方法也很简单,既然是因为DOM渲染时机和获取时机的问题,那么我们只需要等DOM完全渲染好后再去获取DOM 就行了。使用setTimeout

setTimeout(() => {this.initSortable()}, 200)

问题2:

问题1解决后是可以拖拽进行排序了,但是新问题又来了。

这个table是有一个序号的,这个需要用的是table的index属性。但是我拖动排序后,index没有更新。

这是因为渲染机制造成了。只有当table的数据源有新增和减少后才会触发vxe-table的重新渲染。

解决方案:

this.form.item_list = []this.$nextTick(() => {this.form.item_list = [...singleList]})

先将数据源清空,然后重新赋值。只使用nextTick或者重赋值都不能触发vxe-table的重渲染。

http://www.dtcms.com/a/583000.html

相关文章:

  • brew安装JD-GUI并解决启动问题
  • 数组:额外加餐的第二天
  • 网站模板ftpthinkphp网站开发技术
  • php个人网站模板下载电子商务网站前台建设常用的技术有
  • 哈尔滨 房产网站建设wordpress如何清除导入的模板
  • 可做市值曲线的网站建设一个功能简单的网站
  • 【ComfyUI】Wan2.2 动态服饰描述驱动换装图生视频
  • 基于VibeVoice搭建语音合成demo
  • react项目使用json-server模拟接口获取数据
  • 荆州建设局网站邯郸信息港征婚
  • 有口碑的番禺网站建设深圳招聘网最新招聘信息
  • 网站前台如何刷新整合营销案例
  • 可以自己做网站卖东西搜索引擎优化规则
  • C++ this指针、常函数、内联函数
  • 网页设计制作网站大一素材网站集群怎么做
  • Hudson River Trading VO 面经分享|一场关于极限思维与逻辑速度的考验
  • html5企业网站案例企业免费自助建站系统
  • 企业建设网站价格成都专业网站搭建公司
  • 西宁建设网站软件百度导航最新版本免费下载
  • 网站开发后端菜鸟教程网站呢建设
  • JavaScript 使用技巧
  • 提高网站互动性台州住房和城乡建设部网站
  • Spark-3.5.7文档2 - RDD 编程指南
  • 网站公司做网站修改会收费吗电子商务类型的网站
  • flowable使用01
  • 做国外直播网站有哪些渭南seo快速排名
  • 做的网站百度找不到广州市天河区工程建设监督网站
  • 网站攻击方式wordpress手机上用的
  • 攻防世界-Misc-掀桌子
  • 如何用SETNX实现分布式锁