element el-table实现可进行横向拖拽滚动
【问题】表格横向太长,表格横向滚动条位于最底部,需将页面滚动至最底部才可左右拖动表格,用户体验感不好
【需求】基于elment的
el-table组件生成的表格,使其可以横向拖拽滚动【实现】灵感来源于这篇文章【Vue】表格可拖拽滚动,作者已给出原理,感兴趣的可以去了解
找到el-table元素对应的目标元素(VUE3+Element-Plus)
首先给el-table添加ref,并获取元素
<template><el-table :data="tableData" ref="tableRef"></el-table>
</template>
<script lang="ts" setup>
const tableRef = ref(null);
console.log(tableRef);
</script>
我们要找的是包裹table的第一父元素,
.el-scrollbar__wrap类名盒子就是我们要找的目标元素

这里解释一下为什么.el-scrollbar__wrap是父盒子:
我们可以看到.el-scrollbar__view盒子里包裹的是table标签,那么.el-scrollbar__view盒子的宽度就是整个表格的宽度,.el-scrollbar__wrap盒子的宽度又是其父元素的宽度,那么 .el-scrollbar__wrap就是.el-scrollbar__view的父盒子,.el-scrollbar__view子盒子宽度有溢出,.el-scrollbar__wrap父盒子则出现滚动条,使得table可以横向滚动
因此我们要找的目标元素就是
.el-scrollbar__wrap
<template><el-table :data="tableData" ref="tableRef"></el-table>
</template>
<script lang="ts" setup>
const tableRef = ref(null);
//获取目标元素
console.log(tableRef.value.$refs.scrollBarRef.wrapRef);
</script>

实现拖拽横向滚动 (通过改变目标元素的scrollLeft值)
需要捕获鼠标事件及拖拽事件并更改目标元素的scrollLeft值则可实现横向滚动
涉及到的事件包括:mousedown,mouseup,mousemove, mouseleave, dragstart,给表格元素添加相应的事件
mousedown
鼠标按下事件,即鼠标按下但未释放的动作
1.可拖拽状态改为允许拖拽。2.记录鼠标位置。3.鼠标样式改为小手。
tableDataRef.value.$el.addEventListener('mousedown', (e: MouseEvent) => {// 拿到目标元素tableBody = tableDataRef.value.$refs.scrollBarRef.wrapRef;// 拖拽状态改为允许拖拽/鼠标样式修改公共方法setMouseFlag(true, tableBody);// 记录鼠标按下位置mouseStart = e.clientX;// 记录元素当前scrollLeft值startX = tableBody.scrollLeft;// 添加 dragstart 事件监听器document.addEventListener('dragstart', handleDragStart);
});
mousemove
鼠标移动事件,即鼠标在元素内移动的动作
1.判断是否可拖拽。2.允许拖拽时记录鼠标移动距离。3.修改目标元素scrollLeft值。
tableDataRef.value.$el.addEventListener('mousemove', (e: MouseEvent) => {if (mouseFlag) {let offset = e.clientX - mouseStart;(tableBody as HTMLElement).scrollLeft = startX - offset;}
});
mouseup
鼠标释放事件,即鼠标按下后释放的动作
1.可拖拽状态改为禁止拖拽。2.鼠标样式恢复。
tableDataRef.value.$el.addEventListener('mouseup', () => {// console.log('鼠标左键松开++++++++++++');setMouseFlag(false, tableBody);// 移除 dragstart 事件监听器document.removeEventListener('dragstart', handleDragStart);
});
检测到禁止光标手势
监听拖动时,判断是否出现禁止小手标识
如果你选中文字然后点击拖拽时在浏览器中鼠标光标就会变成红色禁止符号
const handleDragStart = (e: DragEvent) => {// console.log('禁止光标手势出现');// 取消默认的拖动效果e.preventDefault();setMouseFlag(false, tableBody);
};
拖拽状态改为允许拖拽/鼠标样式修改公共方法
const setMouseFlag = (flag: boolean, tableBody?: HTMLElement | null) => {mouseFlag = flag;if (tableBody) {tableBody.style.cursor = flag ? 'grab' : 'auto';}
};
封装成统一函数dragTable,并将其定义为全局变量
/src/utils/common.ts
//设置el-table可进行鼠标左键按下左右拖动
interface TableDataRef {value: {$el: HTMLElement;$refs: {scrollBarRef: {wrapRef: HTMLElement;};};};
}export const dragTable = (tableDataRef: TableDataRef) => {let mouseFlag = false,mouseStart = 0,startX = 0,tableBody: HTMLElement | null = null;//鼠标按下事件,即鼠标按下但未释放的动作。tableDataRef.value.$el.addEventListener('mousedown', (e: MouseEvent) => {tableBody = tableDataRef.value.$refs.scrollBarRef.wrapRef;setMouseFlag(true, tableBody);// mouseFlag = true;mouseStart = e.clientX;startX = tableBody.scrollLeft;// tableBody.style.cursor = 'grab';// 添加 dragstart 事件监听器document.addEventListener('dragstart', handleDragStart);});//鼠标释放事件,即鼠标按下后释放的动作。tableDataRef.value.$el.addEventListener('mouseup', () => {// console.log('鼠标左键松开++++++++++++');
/* mouseFlag = false;(tableBody as HTMLElement).style.cursor = 'auto'; */setMouseFlag(false, tableBody);// 移除 dragstart 事件监听器document.removeEventListener('dragstart', handleDragStart);});//鼠标移动事件,即鼠标在元素内移动的动作。tableDataRef.value.$el.addEventListener('mousemove', (e: MouseEvent) => {if (mouseFlag) {let offset = e.clientX - mouseStart;(tableBody as HTMLElement).scrollLeft = startX - offset;}});//鼠标离开事件,即鼠标移动到元素外触发这个事件。tableDataRef.value.$el.addEventListener('mouseleave', (e: MouseEvent) => {handleDragStart((e as any))});// 检测到禁止光标手势const handleDragStart = (e: DragEvent) => {// console.log('禁止光标手势出现');// 取消默认的拖动效果e.preventDefault();setMouseFlag(false, tableBody);};const setMouseFlag = (flag: boolean, tableBody?: HTMLElement | null) => {mouseFlag = flag;if (tableBody) {tableBody.style.cursor = flag ? 'grab' : 'auto';}};
};
main.ts
import { dragTable } from '@/utils/common';
const app = createApp(App);
// 全局方法挂载
app.config.globalProperties.$dragTable = dragTable;
使用全局变量
<template><el-table :data="tableData" ref="tableRef"></el-table>
</template>
<script lang="ts" setup>
import { ComponentInternalInstance, ref } from 'vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const tableRef = ref(null);
nextTick(() => {proxy?.$dragTable(tableRef)
})
</script>
补充(VUE2 + Element)
可参考这篇文章利用 bodyWrapper 实现表格拖动
el-table 中获取 bodyWrapper 的方法
注意:可能存在Element版本差异,建议下面的获取方式都试试
之前获取 bodyWrapper 方法是
this.$refs.myTable.bodyWrapper
现在上面这种方法获取不到了,要更改为
this.$refs.myTable.$elTable.bodyWrapper
或
this.$refs.myTable.$refs.table.bodyWrapper
console.log(this.$refs.mytable)

实现效果
我用的的录制gif软件,鼠标没有变成抓取手势,实际是可以的
如果没有选中文字的需求,可以在mousemove监听中的 if 判断里加上 e.preventDefault();这样拖动时就会很流畅,不受到选中文字影响。


总结
元素可滚动的前提条件是元素的宽度或高度超出给定区域,且开启了滚动条
拖拽需结合mousedown,mousemove,mouseup,mouseleave,dragstart事件实现
竖向滚动同理,修改ScrollTop值即可
相关文章:
element el-table实现可进行横向拖拽滚动
【问题】表格横向太长,表格横向滚动条位于最底部,需将页面滚动至最底部才可左右拖动表格,用户体验感不好 【需求】基于elment的el-table组件生成的表格,使其可以横向拖拽滚动 【实现】灵感来源于这篇文章【Vue】表格可拖拽滚动&am…...
【兔子王赠书第14期】《YOLO目标检测》涵盖众多目标检测框架,附赠源代码和全书彩图!
文章目录 写在前面YOLO目标检测推荐图书本书特色内容简介作者简介 推荐理由粉丝福利写在后面 写在前面 小伙伴们好久不见吖,本期博主给大家推荐一本关于YOLO目标检测的图书,该书侧重目标检测的基础知识,包含丰富的实践内容,是目标…...
WPF 基础入门(样式)
3.1 一般样式 <Grid Margin"10"><TextBlock Text"Style test" Foreground"Red" FontSize"20"/> </Grid> 3.2内嵌样式 直接在控件上定义样式,如下所示: <Grid Margin"10">…...
Java ArrayList在遍历时删除元素
文章目录 1. Arrays.asList()获取到的ArrayList只能遍历,不能增加或删除元素2. java.util.ArrayList.SubList有实现add()、remove()方法3. 遍历集合时对元素重新赋值、对元素中的属性赋值、删除元素、新增元素3.1 普通for循环3.2 增强for循环3.3 forEach循环3.4 str…...
多模态大模型的前世今生
1 引言 前段时间 ChatGPT 进行了一轮重大更新:多模态上线,能说话,会看图!微软发了一篇长达 166 页的 GPT-4V 测评论文,一时间又带起了一阵多模态的热议,随后像是 LLaVA-1.5、CogVLM、MiniGPT-5 等研究工作…...
Android studio 花式按键
一、activity_main.xml代码: <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.a…...
使用spring boot实现异常的统一返回
在这个前后端分离的时代,一个 统一的数据格式非常重要。本次我们实现用spring boot实现一下返回给前端数据的统一格式,不再出现服务器500的错误。 新建一个spring boot项目,并导入knife4j的依赖。 写一个controller控制器,用来是…...
2023-12-11 LeetCode每日一题(最小体力消耗路径)
2023-12-11每日一题 一、题目编号 1631. 最小体力消耗路径二、题目链接 点击跳转到题目位置 三、题目描述 你准备参加一场远足活动。给你一个二维 rows x columns 的地图 heights ,其中 heights[row][col] 表示格子 (row, col) 的高度。一开始你在最左上角的格…...
PID为1的僵尸进程的产生及清理
父进程PID为1的僵尸进程通常是由init系统(在Linux系统中通常是systemd)产生的。这种情况通常发生在以下几种情况: 子进程结束,但其父进程没有正确地调用wait()或waitpid()系统调用来获取子进程的退出状态。在这种情况下࿰…...
043、循环神经网络
之——RNN基础 杂谈 第一个对于序列模型的网络,RNN。 正文 1.潜变量自回归模型 潜变量总结过去的信息,再和当前信息一起结合出新的信息。 2.RNN 循环神经网络将观察作为x,与前层隐变量结合得到输出 其中Whh蕴含了整个模型的时序信息…...
node使用nodemonjs自动启动项目
安装 npm install -g nodemon使用方法 我这里用的是electron项目为例package.json配置 {"name": "my-electron-app","version": "1.0.0","description": "Hello World!","main": "main.js"…...
Ts自封装WebSocket心跳重连
WebSocket是一种在单个TCP连接上进行全双工通信的协议,允许客户端和服务器之间进行双向实时通信。 所谓心跳机制,就是在长时间不使用WebSocket连接的情况下,通过服务器与客户端之间按照一定时间间隔进行少量数据的通信来达到确认连接稳定的手…...
【unity学习笔记】捏人+眨眼效果+口型效果
一、vriod捏人 1.在vroidstudio软件中捏人 2.导出模型(.vrm) 二、vrid导入unity的插件 1.在Git上搜索、打开univrm。 2.找到release页面找到合适的插件版本。(VRM-0.116.0_0f6c) 3.将univrm导入到工程中(assets)。 三…...
动态规划 | 最长公共子序列问题
文章目录 最长公共子序列题目描述问题分析程序代码复杂度分析 最短编辑距离题目描述问题分析程序代码复杂度分析 编辑距离题目描述输入格式输出格式 问题分析程序代码 最长公共子序列 题目描述 原题链接 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共…...
RuntimeError: The NVIDIA driver on your system is too old.
【报错】使用 AutoDL 复现实验时遇到 RuntimeError: The NVIDIA driver on your system is too old (found version 11070). Please update your GPU driver by downloading and installing a new version from the URL: http://www.nvidia.com/Download/index.aspx Alternativ…...
Java开发过程中的幂等性问题
幂等性问题: 1. 有时我们在填写某些 form表单 时,保存按钮不小心快速点了两次,表中竟然产生了两条重复的数据,只是id不一样。 2. 我们在项目中为了解决 接口超时 问题,通常会引入了 重试机制 。第一次请求接口超时了…...
基于Docker的软件环境部署脚本,持续更新~
使用时CtrlF搜索你想要的环境,如果没有你想要的环境,可以评论留言,会尽力补充。 本文提供的部署脚本默认参数仅适合开发测试,请根据实际情况调节参数。 数据库 MySQL version: 3.9 services:mysql:image: mysql:8.0.35container…...
C#上位机与欧姆龙PLC的通信08----开发自己的通讯库读写数据
1、介绍 前面已经完成了7项工作: C#上位机与欧姆龙PLC的通信01----项目背景-CSDN博客 C#上位机与欧姆龙PLC的通信02----搭建仿真环境-CSDN博客 C#上位机与欧姆龙PLC的通信03----创建项目工程-CSDN博客 C#上位机与欧姆龙PLC的通信04---- 欧姆龙plc的存储区 C#上…...
【Redis技术专区】「原理分析」探讨Redis6.0为何需要启用多线程
探讨Redis 6.0为何需要启用多线程 背景介绍开启多线程多线程的CPU核心配置IO多线程模式单线程处理方式多线程处理方式 为什么要开启多线程?充分利用多核CPU提高网络I/O效率响应现代应用需求 多线程实现启用多线程 最后总结 背景介绍 在Redis 6.0版本中,…...
simulink代码生成(六)——多级中断的配置
假如系统中存在多个中断,需要合理的配置中断的优先级与中断向量表;在代码生成中,要与中断向量表对应;中断相关的知识参照博客: DSP28335学习——中断向量表的初始化_中断向量表什么时候初始化-CSDN博客 F28335中断系…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
