当前位置: 首页 > 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;它会在页面的显示区域显示出来。 <…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

Qt 事件处理中 return 的深入解析

Qt 事件处理中 return 的深入解析 在 Qt 事件处理中&#xff0c;return 语句的使用是另一个关键概念&#xff0c;它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别&#xff1a;不同层级的事件处理 方…...