从0到1:Element Plus虚拟树的拖拽功能二次开发实战

一:背景

数据量较大时往往最采用虚拟树形,但是element的虚拟树形并不支持拖拽功能。

根据当前技术栈的选择以及改动成本的大小得出以下几种方案,并进行一一尝试。

方案一:采用vxe-table组件

此组件本身就支持拖动功能,如下图:

优点:

  • 现场的拖动功能
  • 项目中以及引用了此npm依赖包

缺点:

  • 需改动ui风格,成本较大
  • 当前树形组件都是基于element ui封装起来的,,两个组件库API方法不一

方案二:基于当前element 树形组件手写拖动功能

优点:

  • ui风格与当前系统一致
  • API保持一致

缺点:

  • 需自己添加拖动功能
  • 拖动效果达不到预期

2.1 拖动功能实现

2.1.1 借助soetablejs三方库

优点:

  • 现成的拖拽逻辑以及效果

缺点:

  • 效果和预期不一样,且不知能否自定义
2.1.2 原生方式

原生js中存在拖动的APIdrag,但是拖动过程中经过的地方需要展示可放下的效果,如下图

此效果当前的实现思路是进行计算,但是实时计算耗能较大,且容易不精准,既然element存在此功能,边打开控制台查看下能否寻到灵感。

发现了如下打印:

分析关键字:enteroverleave,然我网上查询资料得到以下API:

网站:developer.mozilla.org/zh-CN/docs/...

由此可见拖动过程的开始拖动移入移除结束拖动等事件都是有原生API的,借助此类API便可实现想要的效果

拖动功能初步实现进行以下操作即可

  • 元素开启deaggable属性
2.2 移入效果实现

思路:

  • deagenter移入事件记录当前鼠标移入的元素
  • 动态类决定当前是否显示移入效果

    • 再已有基础上增加了禁止拖入的红色效果
2.3 拖动效果自定义

经资料查询,原生API有一个event.dataTransfer.serDragImage的方法可以设置拖动的样式,最开始以为只能传图片,但是图片不能满足效果,又尝试了拖动过程中实时根据鼠标位置进行悬浮dom定位,但是此方式性能较差,移动快了容易跟随慢一拍。再经常尝试,其实原生api支持dom传入。最终实现如下:

  • 拖动开始借助dragStart方法根据当前拖动的节点进行拖动样式的变化

  • 自定义样式使用一个新的tree组件,保持拖动效果同当前一致

    • 拖动样式进行优化,最多显示三个子级

dom增加事件回调

js逻辑处理

自定义样式dom

效果:

2.4 拖动过程中事件增加

拖动过程中判断能否拖入的逻辑需要再此处处理,长远考虑拖动功能可能其他模块也要用,所以拖动功能便和已有的树形组件封装再一起,然后通过传参的方式进行开启,相关事件均和普通树形API以及使用方式 保持一致,此方法要在移入结束拖拽事件中都生效,所以实现如下:

  • enter中触发此方法

  • end中触发此方法

    • 当然如果没有此方法则代表都可拖入,优先才有proop传下来的方法
2.5 占位符效果实现

思路如下:

  • 获取当前点击的node节点数据
  • 添加新的节点
  • 展开当前节点(可能是折叠状态)
  • 滚动到新添加的节点位置

代码如下

代码如下:

注意事项:

占位符添加时机 ,要再内容区滚动结束后再调用,否则会影响右侧内容定位的精准度,因为右侧滚动条定位是需要再浏览器当前帧绘制完成后才滚动的,若绘制过程中左侧树形又发生绘制,则会导致右侧内容区定位不准。

3、问题优化

3.1、 滚动条拖拽问题优化:

当前问题:鼠标拖动滚动条时整体发生偏移,且影响后续滚动事件,如下图:

原因:对组件整体开启了deaggable属性

解决方案:修改传参

3.2 新增时定位优化

当前定位时右侧内容区不能精准的滚动到对应位置。

解决思路如下:

  • 只要是新增,右侧内容区便采用分页逻辑,重新对数据进行截取
  • 截取完成后添加新节点
  • 滚动到新节点位置,使其置顶
  • 其余步骤保持一致

至此虚拟树形的拖拽效果以及使用方式以及和element 普通树形的效果以及使用方式保持一致,并且再某些效果上更佳。

相关推荐
xiaominlaopodaren15 分钟前
Three.js 光影魔法:如何单独点亮你的3D模型
javascript
PasserbyX16 分钟前
一句话解释JS链式调用
前端·javascript
1024小神18 分钟前
tauri项目,如何在rust端读取电脑环境变量
前端·javascript
古夕27 分钟前
如何将异步操作封装为Promise
前端·javascript
@一枝梅33 分钟前
vue3 vite.config.js 引入bem.scss文件报错
javascript·rust·vue·scss
古夕38 分钟前
JS 模块化
前端·javascript
一只小风华~41 分钟前
HTML前端开发:JavaScript 常用事件详解
前端·javascript·html
Revol_C44 分钟前
【调试日志】我只是用wangeditor上传图片而已,页面咋就崩溃了呢~
前端·vue.js·程序员
HelloWord~1 小时前
SpringSecurity+vue通用权限系统2
java·vue.js
bysking2 小时前
【27-vue3】vue3版本的"指令式弹窗"逻辑函数createModal-bysking
前端·vue.js