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

基于element UI 实现 table 列 拖拽

问题描述

在开发中遇到一个需求,即实现table列的拖拽,但是调研发现,大部分是基于sorttable.js这个包实现的,但是通过实际应用,发现sorttable.js用在操作element table 组件中并不是很舒服,总会莫名其妙的冒出一些异常bug,于是自行封装一个table 列拖拽组件。

难点概括

①element table header插槽应用

②drag知识点应用

③splice()方法理解

演示代码

<template><div><h1>基于element-ui table列拖拽实现</h1><drag-head :head-columns="tableHead" :data="tableData"></drag-head></div>
</template>
<script>
import DragHead from "./dragHead.vue";export default {name: "DragHeadCase",components: { DragHead },data() {return {tableHead: [{label: "零零",prop: "v0",width: 150,},{label: "一一",prop: "v1",width: 150,},{label: "二二",prop: "v2",width: 150,},{label: "三三",prop: "v3",width: 150,},{label: "四四",prop: "v4",width: 300,},{label: "五五",prop: "v5",},{label: "六六",prop: "v6",},{label: "七七",prop: "v7",},{label: "八八",prop: "v8",},{label: "九九",prop: "v9",},],tableData: [{v0: "2016-05-02",v1: "王小虎",v2: "上海",v3: "普陀区",v4: "上海市普陀区金沙江路 1518 弄",v5: 200333,v6: "2016-05-02",v7: "王小虎",v8: "上海",v9: "普陀区",},{v0: "2016-05-02",v1: "王小虎",v2: "上海",v3: "普陀区",v4: "上海市普陀区金沙江路 1518 弄",v5: 200333,v6: "2016-05-02",v7: "王小虎",v8: "上海",v9: "普陀区",},{v0: "2016-05-02",v1: "王小虎",v2: "上海",v3: "普陀区",v4: "上海市普陀区金沙江路 1518 弄",v5: 200333,v6: "2016-05-02",v7: "王小虎",v8: "上海",v9: "普陀区",},{v0: "2016-05-02",v1: "王小虎",v2: "上海",v3: "普陀区",v4: "上海市普陀区金沙江路 1518 弄",v5: 200333,v6: "2016-05-02",v7: "王小虎",v8: "上海",v9: "普陀区",},{v0: "2016-05-02",v1: "王小虎",v2: "上海",v3: "普陀区",v4: "上海市普陀区金沙江路 1518 弄",v5: 200333,v6: "2016-05-02",v7: "王小虎",v8: "上海",v9: "普陀区",},],};},
};
</script>

table 列 拖拽组件实现代码

<template><div style="width: 1000px"><el-tableref="elTable"borderstyle="width: 100%"v-bind="$attrs"v-on="$listeners":key="headKey":cell-class-name="cellClassName":header-cell-class-name="cellClassName"><!-- 循环表头 --><template v-for="(col, index) in tableHead"><el-table-column:key="index":prop="col.prop":align="col.align || 'center'":width="col.width || 100"><!-- 通过插槽为表头绑定mousedown和dragover方法 --><template slot="header" slot-scope="{ column, $index }"><span@mousedown="handleMounseDown($event, column, $index)"@dragover="handleDragover($event, column, $index)">{{ col.label }}</span></template></el-table-column></template></el-table></div>
</template><script>
export default {props: {headColumns: Array,},mounted() {/** 备用操作(如果需要对headColumns数组操作) */this.tableHead = this.headColumns;},data() {return {tableHead: [],// 拖拽状态dragState: {start: -3, // 起始元素的 index 防止初始化cellStyle时序号、展开等默认样式改变,最好小于-3end: -3, // 移动鼠标时所覆盖的元素 indexdragging: false, // 是否正在拖动direction: undefined, // 拖动方向},headKey: "dragHead", // 表头数组变换位置时,重绘table(不更新该值,表头数组变化时,页面不会改变)scrollX: 0, // 初始x轴scroll位置(用于定位X轴滚动条)};},methods: {/** 鼠标摁下触发 */handleMounseDown(e, column, $index) {this.dragState.dragging = true;this.dragState.start = parseInt($index - 0);// 添加鼠标抬起事件  消除鼠标摁下立刻松开问题document.addEventListener("mouseup", this.handleMouseUp);// 添加拖拽结束事件document.addEventListener("dragend", this.handleMouseUp);// 对选中的表头允许其拖拽const dragclass = ".el-table__header-wrapper ." + column.id;const dragDom = document.querySelectorAll(dragclass);dragDom.forEach((dom) => {// 允许表头块可以被拖拽 draggable 属性 不允许拖拽dragover等相关拖拽事件无法触发dom.setAttribute("draggable", true);});},/** 鼠标在拖拽移动时触发 */handleDragover(e, column, $index) {if (this.dragState.dragging) {// 获取当前滚动条的位置const scrollDom = this.$refs.elTable.bodyWrapper;this.scrollX = scrollDom.scrollLeft;const index = parseInt($index - 0); // 记录起始列/** 实时更改鼠标处于表头的位置 */if (index - this.dragState.start !== 0) {this.dragState.direction =index - this.dragState.start < 0 ? "left" : "right"; // 判断拖动方向this.dragState.end = parseInt($index - 0);} else {this.dragState.end = this.dragState.start;this.dragState.direction = null;}}},/** 鼠标抬起或拖拽结束触发 */handleMouseUp() {// 更新拖拽后的表头this.headDraged(this.dragState);const { end } = this.dragState;// 初始化拖动状态this.dragState = {start: end, //记录最后拖动的位置end: -9,dragging: false,direction: undefined,};document.removeEventListener("mouseup", this.handleMouseUp);document.removeEventListener("dragend", this.handleMouseUp);setTimeout(() => {// 重置拖拽状态this.dragState.start = -9;}, 500);},// 更新拖拽后的表头headDraged({ start, end, direction }) {if (direction) {const originColumn = this.tableHead[start];// 有位置交换时,原先位置的元素删除,再在目标处插入this.tableHead.splice(start, 1);this.tableHead.splice(end, 0, originColumn);this.headKey = new Date().getTime() + ""; // 更新table key值this.$nextTick(() => {// 因为表头重绘后滚动条会移到最左端初始位置,因此如果是在中间部分拖拽,还需要把滚动条在定位到该位置this.$refs.elTable.bodyWrapper.scrollLeft = this.scrollX;});}},// 拖动虚线样式设置cellClassName({ columnIndex }) {const { start, end, direction } = this.dragState;const target = columnIndex - 0;if (target === start) {// 被移动的元素return "drag_start";} else if (target === end) {// 要移动的位置return `drag_end_${direction}`;}return "";},},
};
</script><style lang="scss" scoped>
::v-deep .el-table {.drag_start {opacity: 0.8;background-color: rgba(0, 0, 0, 0.938);color: #f3e8e8fd;transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);}.drag_end_left {border-left: 2px dotted rgba(0, 0, 0, 0.938);}.drag_end_right {border-right: 2px dotted rgba(0, 0, 0, 0.938);}
}
</style>

然后我在操作的时候碰到一个报错

[Violation ] Added non-passive event listener to ascroll- blocking 'mousewheel’event Consider marking event handler as ’ passive’to make the page more responsive. See https: com/feature/574554 3795965952

翻译:

[冲突]在ascroll中添加了非被动事件侦听器-阻塞“mousewheel”事件考虑将事件处理程序标记为“passive”,以使页面更具响应性。参见https:com/feature/574554 3795965952

解决办法:

npm i default-passive-events -S
main.js import 'default-passive-events'

最后

该组件目前仅支持最简单的拖拽效果,后续开发出兼容fixed、checkbox、expand 以及操作列的组件会及时更新文章,有兴趣的朋友可以点赞收藏。

参考文献

基于element UI 实现 table 列 拖拽_element table列拖拽_淡然自若_blog的博客-CSDN博客

Added non-passive event listener to ascroll- blocking ‘mousewheel‘event Consider marking event handl_绅士的可怖的博客-CSDN博客

相关文章:

基于element UI 实现 table 列 拖拽

问题描述 在开发中遇到一个需求&#xff0c;即实现table列的拖拽&#xff0c;但是调研发现&#xff0c;大部分是基于sorttable.js这个包实现的&#xff0c;但是通过实际应用&#xff0c;发现sorttable.js用在操作element table 组件中并不是很舒服&#xff0c;总会莫名其妙的冒…...

(GPT、GEE)遥感云大数据、洪涝灾害监测、红树林遥感制图、河道轮廓监测、洪涝灾害监测、GRACE重力卫星、源遥感影像

近年来遥感技术得到了突飞猛进的发展&#xff0c;航天、航空、临近空间等多遥感平台不断增加&#xff0c;数据的空间、时间、光谱分辨率不断提高&#xff0c;数据量猛增&#xff0c;遥感数据已经越来越具有大数据特征。遥感大数据的出现为相关研究提供了前所未有的机遇&#xf…...

vue中实现将页面或者div内容导出为pdf格式

将Vue单页面转成pdf并下载 步骤1&#xff1a;下载对应的库 npm install html2canvas;npm install jspdf --save 步骤2&#xff1a;创建一个htmlToPdf.js的js文件, 然后在main.js中全局引用一下&#xff0c;编写如下代码&#xff1a; // htmlToPdf.js // 导出页面为PDF格式 …...

Ubuntu 配置国内源

配置国内源 因为众所周知的原因&#xff0c;国外的很多网站在国内是访问不了或者访问极慢的&#xff0c;这其中就包括了Ubuntu的官方源。 所以&#xff0c;想要流畅的使用apt安装应用&#xff0c;就需要配置国内源的镜像。 市面上Ubuntu的国内镜像源非常多&#xff0c;比较有…...

分布式核心知识

文章目录 前言一、分布式中的远程调用1.1RESTful接口1.2RPC协议1.3区别与联系 二、分布式中的CAP原理 前言 关于分布式核心知识详解 一、分布式中的远程调用 在微服务架构中&#xff0c;通常存在多个服务之间的远程调用的需求。远程调用通常包含两个部分&#xff1a;序列化和通…...

【JMeter】常用线程组设置策略

目录 一、前言 二、单场景基准测试 1.介绍 2.线程组设计 3.测试结果 三、单场景并发测试 1.介绍 2.线程组设计 3.测试结果 四、单场景容量/爬坡测试 1.介绍 2.线程组设计 3.测试结果 五、混合场景容量/并发测试 1.介绍 六、稳定性测试 1.介绍 2.线程组设计 …...

【数据结构】回溯算法公式化解题 leetcode经典题目带刷:全排列、组合、子集

目录 回溯算法一、什么是回溯算法1、基本思想&#xff1a;2、一般步骤&#xff1a; 二、题目带练1、全排列2、组合3、子集 三、公式总结 回溯算法 一、什么是回溯算法 回溯算法&#xff08;Backtracking Algorithm&#xff09;是一种解决组合问题、排列问题、选择问题等一类问…...

WPF基础入门-Class3-WPF数据模板

WPF基础入门 Class3&#xff1a;WPF数据模板 1、先在cs文件中定义一些数据 public partial class Class_4 : Window{public Class_4(){InitializeComponent();List<Color> test new List<Color>();test.Add(new Color() { Code "Yellow", Name &qu…...

js将搜索的关键字加颜色

js将搜索的关键字加颜色 使用正则匹配关键字并加入span标签&#xff0c;页面渲染时使用v-html渲染即可 // 文本框内容 let searchCont 测试;const reg new RegExp((${searchCont.value}), g); let data 图片保存测试A; data data.replace(reg, <span style"color:…...

Docker安装Oracle数据库打开、链接速度很慢

问题&#xff1a; 使用Docker安装Oracle数据库打开、链接速度很慢&#xff0c;明显的在在转圈严重影响效率。 解决&#xff1a; 排查到DNS时&#xff0c;发现宿主机DNS配置清空后&#xff0c;通过JDBC连接目标Oracle数据库速度很快 进入容器中进行测试&#xff0c;发现清空DNS…...

学生分班查询系统的创建与使用指南

开学季&#xff0c;负责分班工作的老师们又面临一个难题&#xff1a;如何公布分班结果&#xff1f;将结果放在学校官网上可能会让很多无关人员看到&#xff0c;而不放则会导致家长们纷纷打电话来询问。那么&#xff0c;有没有一种方法可以让家长们自行查看分班结果呢&#xff1…...

全套解决方案:基于pytorch、transformers的中文NLP训练框架,支持大模型训练和文本生成,快速上手,海量训练数据!

全套解决方案&#xff1a;基于pytorch、transformers的中文NLP训练框架&#xff0c;支持大模型训练和文本生成&#xff0c;快速上手&#xff0c;海量训练数据&#xff01; 1.简介 目标&#xff1a;基于pytorch、transformers做中文领域的nlp开箱即用的训练框架&#xff0c;提…...

ffmpeg

文章目录 libavcodec实现 libavformat实现libavfilter实现 libswscale实现对比libavfilter图像处理libswscale vs libyuvlibavutil 命令行工具ffmpeg例子 ffprobe例子 FFmpeg 是一个由 C 语言编写的开源跨平台音视频处理工具集&#xff0c;它具有模块化的架构。下面是 FFmpeg 的…...

CH03_代码的坏味道(下)

循环语句&#xff08;Loops&#xff09; 从最早的编程语言开始&#xff0c;循环就一直是程序设计的核心要素。如今&#xff0c;函数作为一等公民已经得到了广泛的支持&#xff0c;因此我们可以使用以管道取代循环&#xff08;231&#xff09;管道操作&#xff08;如filter和ma…...

journal日志导致服务器磁盘满

背景 ubuntu 18.04服务器磁盘突然100% 一查/var/log/journal目录占了14G 清理 要清理 journal 日志&#xff0c;可以使用以下步骤&#xff1a; 运行以下命令来查看 journal 日志的使用情况&#xff1a; journalctl --disk-usage这将显示 journal 日志的当前使用情况&#x…...

“Go程序员面试笔试宝典”复习便签

一.逃逸分析 1.1逃逸分析是什么&#xff1f; 逃逸分析&#xff0c;主要是Go编译器用来决定变量分配在堆或者栈的手段。 区分于C/C手动管理内存分配&#xff0c;Go将这些工作交给了编译器。 1.2逃逸分析有什么作用 解放程序员。程序员不需要手动指定指针分配内存。 灵活的…...

数组的度(指数组里任一元素出现频数的最大值)

题目&#xff1a; 给定一个非空且只包含非负数的整数数组 nums&#xff0c;数组的 度 的定义是指数组里任一元素出现频数的最大值。 你的任务是在 nums 中找到与 nums 拥有相同大小的度的最短连续子数组&#xff0c;返回其长度。 示例 1&#xff1a; 输入&#xff1a;nums …...

scala array类型参数

在Scala中&#xff0c;数组&#xff08;Array&#xff09;是一种用于存储相同类型元素的数据结构。数组可以用于保存基本数据类型和自定义数据类型的元素。当定义数组类型参数时&#xff0c;您通常是在函数、类或方法签名中使用它们。以下是一些有关Scala数组类型参数的示例&am…...

构建 NodeJS 影院预订微服务并使用 docker 部署(03/4)

一、说明 构建一个微服务的电影网站&#xff0c;需要Docker、NodeJS、MongoDB&#xff0c;这样的案例您见过吗&#xff1f;如果对此有兴趣&#xff0c;您就继续往下看吧。 你好社区&#xff0c;这是&#x1f3f0;“构建 NodeJS 影院微服务”系列的第三篇文章。本系列文章演示了…...

html写一个向flask_socketio发送消息和接收消息并显示在页面上

以下是一个简单的HTML页面&#xff0c;它包含一个输入框、一个发送按钮和一个显示区域。用户可以在输入框中输入消息&#xff0c;点击发送按钮&#xff0c;然后这个消息会被发送到 Flask-SocketIO 服务器。当服务器回应消息时&#xff0c;它会在页面的显示区域显示出来。 <…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...