用 Vue 3 实现一个拖拽排序表格组件(支持列/行重排、列宽调整)

文章目录

  • 一、项目初始化
    • 1.1 技术栈说明
    • 1.2 项目结构图(Mermaid)
  • 二、构建基础表格组件
    • 2.1 创建基本表格结构
  • 三、实现行拖拽排序
    • 3.1 安装依赖
    • 3.2 使用 `vuedraggable` 实现拖拽
  • 四、实现列宽拖拽调整
    • 4.1 基本样式设置
    • 4.2 添加拖拽逻辑
  • 五、实现列拖拽排序
    • 5.1 转换列为可拖拽结构
    • 5.2 保证数据对应正确列
  • 六、可拓展功能实现
    • 6.1 固定列实现(示意)
    • 6.2 列顺序保存到本地存储
  • 七、总结

一、项目初始化

1.1 技术栈说明

  • Vue 3 Composition API
  • vuedraggable:用于实现拖拽排序
  • 原生 DOM 操作:用于列宽调整
  • Element Plus(可选):用于样式和表格基础结构

1.2 项目结构图(Mermaid)

App.vue
TableComponent.vue
RowDraggable.vue
ColResizable.vue

二、构建基础表格组件

2.1 创建基本表格结构

<!-- TableComponent.vue -->
<template><div class="table-container"><table><thead><tr><th v-for="(col, index) in columns" :key="col.key">{{ col.label }}</th></tr></thead><tbody><tr v-for="(row, rowIndex) in tableData" :key="row.id"><td v-for="col in columns" :key="col.key">{{ row[col.key] }}</td></tr></tbody></table></div>
</template><script setup>
import { ref } from 'vue'const columns = ref([{ label: '姓名', key: 'name' },{ label: '年龄', key: 'age' },{ label: '地址', key: 'address' }
])const tableData = ref([{ id: 1, name: '小明', age: 25, address: '北京' },{ id: 2, name: '小红', age: 30, address: '上海' },{ id: 3, name: '小刚', age: 28, address: '广州' }
])
</script>

三、实现行拖拽排序

3.1 安装依赖

npm install vuedraggable

3.2 使用 vuedraggable 实现拖拽

<template><draggable v-model="tableData" tag="tbody" item-key="id"><tr v-for="row in tableData" :key="row.id"><td v-for="col in columns" :key="col.key">{{ row[col.key] }}</td></tr></draggable>
</template><script setup>
import draggable from 'vuedraggable'
</script>

四、实现列宽拖拽调整

4.1 基本样式设置

th {position: relative;padding-right: 8px;
}.resizer {position: absolute;top: 0;right: 0;width: 5px;cursor: col-resize;user-select: none;
}

4.2 添加拖拽逻辑

<thv-for="(col, index) in columns":key="col.key":style="{ width: col.width + 'px' }"@mousedown="startResize($event, index)"
>{{ col.label }}<span class="resizer"></span>
</th>let startX, startWidthconst startResize = (e, index) => {startX = e.clientXstartWidth = columns.value[index].width || 100document.addEventListener('mousemove', resize)document.addEventListener('mouseup', stopResize)function resize(e) {const newWidth = startWidth + (e.clientX - startX)columns.value[index].width = Math.max(newWidth, 60)}function stopResize() {document.removeEventListener('mousemove', resize)document.removeEventListener('mouseup', stopResize)}
}

五、实现列拖拽排序

5.1 转换列为可拖拽结构

<draggable v-model="columns" tag="tr" item-key="key" direction="horizontal"><thv-for="(col, index) in columns":key="col.key":style="{ width: col.width + 'px' }"@mousedown="startResize($event, index)">{{ col.label }}<span class="resizer"></span></th>
</draggable>

5.2 保证数据对应正确列

<tr v-for="row in tableData" :key="row.id"><td v-for="col in columns" :key="col.key">{{ row[col.key] }}</td>
</tr>

六、可拓展功能实现

6.1 固定列实现(示意)

<th :class="{ 'sticky-left': index === 0 }"> ... </th>
.sticky-left {position: sticky;left: 0;background-color: #fff;z-index: 2;
}

6.2 列顺序保存到本地存储

watch(columns, (val) => {localStorage.setItem('columns', JSON.stringify(val))
}, { deep: true })onMounted(() => {const saved = localStorage.getItem('columns')if (saved) {columns.value = JSON.parse(saved)}
})

七、总结

通过本文,我们使用 Vue 3 实现了一个具备以下功能的可配置表格组件:

  • ✅ 行拖拽排序
  • ✅ 列宽度调整
  • ✅ 列顺序拖拽
  • ✅ 固定列支持
  • ✅ 用户列设置持久化

该组件可广泛应用于数据管理后台、内容管理系统等场景,未来可继续拓展如列隐藏、分组列头、自定义渲染等功能。


到这里,这篇文章就和大家说再见啦!我的主页里还藏着很多 篇 前端 实战干货,感兴趣的话可以点击头像看看,说不定能找到你需要的解决方案~
创作这篇内容花了很多的功夫。如果它帮你解决了问题,或者带来了启发,欢迎:
点个赞❤️ 让更多人看到优质内容
关注「前端极客探险家」🚀 每周解锁新技巧
收藏文章⭐️ 方便随时查阅
📢 特别提醒:
转载请注明原文链接,商业合作请私信联系
感谢你的阅读!我们下篇文章再见~ 💕

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/901725.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python异常处理全面指南

目录 一、异常处理概述 1.1 什么是异常&#xff1f; 1.2 常见异常类型示例 二、基础异常捕获 2.1 简单异常捕获语法 2.2 特定异常类型捕获 三、高级异常处理技术 3.1 完整异常处理语法 3.2 异常传递机制 四、主动抛出异常 4.1 自定义异常抛出 4.2 创建自定义异常类 …

基于混沌映射的LDPC信道编译码matlab性能仿真,对比LDPC

目录 1.算法仿真效果 2.算法涉及理论知识概要 2.1 混沌映射 2.2 基于混沌映射的LDPC编译码 3.MATLAB核心程序 4.完整算法代码文件获得 1.算法仿真效果 matlab2022a仿真结果如下&#xff08;完整代码运行后无水印&#xff09;&#xff1a; 仿真操作步骤可参考程序配套的操…

学点概率论,打破认识误区

概率论是统计分析和机器学习的核心。掌握概率论对于理解和开发稳健的模型至关重要&#xff0c;因为数据科学家需要掌握概率论。本博客将带您了解概率论中的关键概念&#xff0c;从集合论的基础知识到高级贝叶斯推理&#xff0c;并提供详细的解释和实际示例。 目录 简介 基本集合…

【数据结构_9】栈和队列

队列 Queue 一个方向进&#xff0c;一个方向出 Queue队列提供的核心方法&#xff1a; 入队列&#xff1a;offer add 出队列&#xff1a;poll remove 取队首元素&#xff1a; peek element 前面一列发生错误是返回null 后面一列发生错误时抛出异常 Queue是否能够使用isEm…

HarmontOS-ArkUI V2状态 !!语法糖 双向绑定

什么是双向绑定 双向绑定指的是在组件间数据的双向绑定。当一个值无论是在父组件还是子组件中改动都会在这两层中都更新界面。 回顾过往的“双向绑定”实现方式 靠@Event装饰回调函数 一般是对于@Param修饰的状态变量。当子组件发生某个动作的时候,调用某个父组件传递过来的…

贪心算法day9(合并区间)

1.合并区间 56. 合并区间 - 力扣&#xff08;LeetCode&#xff09; 对于这种区间问题&#xff0c;我们应该先排序根据排序的结果总结一些规律&#xff0c;进而的得出解决该问题的策略。 class Solution {public static int[][] merge(int[][] intervals) {//第一步进行左端点…

探索加密期权波动率交易的系统化实践——动态对冲工具使用

Trading Volatility – What Are My Options? 在本文中&#xff0c;我们将介绍一些如何交易资产波动性&#xff08;而非资产价格&#xff09;的示例。为了帮助理解&#xff0c;我们将使用 Deribit 上提供的几种不同产品&#xff0c;包括但不限于期权。我们将尽可能消除对标的价…

子函数嵌套的意义——以“颜色排序”为例(Python)

多一层缩进精减参数传递&#xff0c;参数少平铺书代码写更佳。 笔记模板由python脚本于2025-04-16 11:52:53创建&#xff0c;本篇笔记适合喜欢子函数嵌套结构代码形式的coder翻阅。 【学习的细节是欢悦的历程】 博客的核心价值&#xff1a;在于输出思考与经验&#xff0c;而不仅…

【数据结构与算法】LeetCode每日一题

此题跟27.移除数组中的指定值 类似&#xff0c;都是移除且双指针玩法&#xff0c;只不过判断条件发生了变化 此题跟26.删除有序数组中的重复项I 一样&#xff0c;除了fast-1变成了fast-2

c#OleDb连接池管理功能

使用 ConcurrentDictionary 和 ConcurrentBag 来管理数据库连接 using Drv.Utilities; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Data.OleDb; using System.Linq;namespace Drv.AccessClient {/// <summary>…

【Flink运行时架构】核心组件

在Flink的运行架构中&#xff0c;有两大比较重要的组件&#xff1a;作业管理器&#xff08;JobManager&#xff09;和任务管理器&#xff08;TaskManager&#xff09;。 Flink的作业提交与任务处理时的系统如下图所示。 其中&#xff0c;客户端并不是处理系统的一部分&#xff…

牟乃夏《ArcGIS Engine地理信息系统开发教程》学习笔记2

目录 一、ArcGIS Engine概述 1、 定义 2、 核心功能 3、 与ArcObjects&#xff08;AO&#xff09;的关系 二、开发环境搭建 1、 开发工具要求 2、 关键步骤 三、 ArcGIS Engine核心组件 1、 对象模型 2、 类库分类 四、 第一个AE应用程序&#xff08;C#示例&#xf…

端、管、云一体化原生安全架构 告别外挂式防护!

面对数字化转型浪潮&#xff0c;企业网络安全风险日益凸显。数据泄露、黑客勒索等事件频发&#xff0c;合规要求加速推进。尽管企业纷纷部署了防病毒、身份认证、文件加密、入侵防护、流量监控等多种安全系统&#xff0c;但分散且孤立的架构非但没有有效抵御风险&#xff0c;反…

深度学习--深度学习概念、框架以及构造

文章目录 一、深度学习1.什么是深度学习&#xff1f;2.特点3.神经网络构造1&#xff09;.单层神经元2&#xff09;多层神经网络3&#xff09;小结 4.感知器5.多层感知器6.多层感知器&#xff08;偏置节点&#xff09;7.神经网络构造 一、深度学习 1.什么是深度学习&#xff1f…

helm账号密码加密

1、安装工具 sudo apt update sudo apt install gnupg -y wget https://github.com/getsops/sops/releases/download/v3.10.2/sops-v3.10.2.linux.amd64 mv sops-v3.10.2.linux.amd64 /usr/local/bin/sops chmod x /usr/local/bin/sops2、生成加密文件 gpg --full-generate-…

大数据面试问答-HBase/ClickHouse

1. HBase 1.1 概念 HBase是构建在Hadoop HDFS之上的分布式NoSQL数据库&#xff0c;采用列式存储模型&#xff0c;支持海量数据的实时读写和随机访问。适用于高吞吐、低延迟的场景&#xff0c;如实时日志处理、在线交易等。 RowKey&#xff08;行键&#xff09; 定义&#xf…

动态渲染组件

React框架&#xff0c;JSX语法 今天遇到一个好玩的 常规的搜索列表&#xff0c;列表最后一列为操作列&#xff0c;删改查。 眼看着Table 操作列 的配置文件越来越复杂&#xff0c;决定把操作列单独写一个组件&#xff0c;代码瞬间靓仔了些 {title: Operation,dataIndex: oper…

Web APIs阶段

一、Web APIs和JS基础关联性 1.1JS的组成 1.2JS基础阶段以及Web APIs阶段 JS基础阶段&#xff1a;学习的是ECMAScript标准规定的基础语法 Web APIs阶段&#xff1a; Web APIs是W3C组织的标准Web APIs我们主要学习DOM和BOMWeb APIs是JS独有的部分主要学习页面交互功能需要使用…

Doip功能寻址走UDP协议

目前使用 connect()函数的UDP客户端 ,这里接收数据 解析的地方 查看一下。 如果使用 bind()、sendto()、recvfrom() 组合 那么返回值 和发送要在做调整&#xff0c;&#xff0c;根据业务需要后续在调整 其余的 和原来的 逻辑都是一样的&#xff0c;只是协议变了而已。 if serv…

Linux指令的详细介绍

前言&#xff1a;&#x1f33c;&#x1f33c; Linux是一款强大且广泛使用的操作系统&#xff0c;命令行接口&#xff08;CLI&#xff09;是与其交互的核心方式。通过Linux指令&#xff0c;用户可以高效地执行文件管理、系统监控、进程控制等任务。虽然刚接触时可能感到有些复杂…