Vue下 Sortable 实现 table 列表字段可拖拽排序,显示隐藏组件开发

vue 开发table 列表时,需要动态调整列字段的顺序和显示隐藏

实现效果如图所示:

在这里插入图片描述

vue 组件代码

<template><div style="width: 90%; margin: 0 auto;"><el-table :data="tableData" border="" ref="tableNode" @selection-change="handleSelectionChange" :height="windowHeight - 200" v-loading="loading" row-key="field"><el-table-column type="selection" width="70"></el-table-column><el-table-column prop="fieldName" label="列名"></el-table-column><el-table-column prop="sortNum" label="排序"><template slot-scope="scope">{{ scope.$index + 1 }}</template></el-table-column></el-table><div style="display: flex; justify-content: flex-end; padding-top: 20px;"><el-button @click="reset" size="mini">取消</el-button><el-button type="primary" @click="submit" size="mini">保存</el-button></div></div>
</template><script>
import { setPageFieldSort, getPageFieldSort } from "@/api/public";
import Sortable from "sortablejs";export default {name: 'listFieldSet',data() {return {pageName: "",tableData: [],multipleSelection: [],selectedRowsBackup: [],loading: false,windowHeight: window.innerHeight,}},updated() {this.$nextTick(() => {this.$refs.tableNode.doLayout()})},mounted() {window.addEventListener('resize', this.handleResize);},beforeDestroy() {window.removeEventListener('resize', this.handleResize);},methods: {handleResize() {this.windowHeight = window.innerHeight;},initData(pageName) {this.pageName = pageName;if (this.tableData && this.tableData.length === 0) {this.loading = true;getPageFieldSort({'pageName': pageName}).then(res => {this.tableData = res.data;if (this.tableData) {this.tableData.forEach(item => {if (item.isShow) {this.multipleSelection.push(item.field);this.$nextTick(() => {this.$refs.tableNode.toggleRowSelection(item, true);});}});}}).finally(() => {this.loading = false;});//声明表格拖动排序方法this.pullSort();}},//    //表格拖动排序方法pullSort() {// 通过ref获取Dom节点const el = this.$refs.tableNode.$el.querySelectorAll(".el-table__body-wrapper > table > tbody")[0];this.sortable = Sortable.create(el, {animation: 200, //拖拽动画(毫秒)setData: function (dataTransfer) {dataTransfer.setData("Text", "");},onStart: () => {// 拖拽开始前保存当前选中的行this.selectedRowsBackup = [...this.multipleSelection];},// 结束拖拽onEnd: (evt) => {const movedItem = this.tableData.splice(evt.oldIndex, 1)[0];this.tableData.splice(evt.newIndex, 0, movedItem);this.$nextTick(() => {this.selectedRowsBackup.forEach(row => {const targetRow = this.tableData.find(item => item.field === row);if (targetRow) {this.$refs.tableNode.toggleRowSelection(targetRow, true); // 重新选中}});})},});},handleSelectionChange(rows) {this.multipleSelection = rows.map(row => row.field);},reset() {this.$emit('close');},submit() {this.loading = true;this.tableData.forEach(item => {item.isShow = this.multipleSelection.findIndex(row => row === item.field) > -1;});setPageFieldSort({'fields': this.tableData,'pageName': this.pageName}).then(res => {this.$message.success("保存成功");}).finally(() => {this.loading = false;});},}
}
</script>

列表字段实例数据

[{"id": 449,"userCode": "klfadmin","field": "id","pageName": "projectLaborManagement","sortNum": 1,"isShow": 1,"fieldName": "序号"},{"id": 450,"userCode": "klfadmin","field": "title","pageName": "projectLaborManagement","sortNum": 2,"isShow": 1,"fieldName": "劳务标题"},{"id": 451,"userCode": "klfadmin","field": "state","pageName": "projectLaborManagement","sortNum": 3,"isShow": 1,"fieldName": "状态"}
]

代码说明

  1. template 普通的表格列表展示,主要展示所有的可设置的字段

    • @selection-change 勾选时触发事件,存储一下勾选项,记录的是每行的 field 字段
    • :height 是设置容器的高度,此处是自动适应窗口高度。实现逻辑可参考 前面的文章
  2. initData 方法,加载列表字段,见上的实例数据,此处是接口加载。请求的数据是 第4步存储的数据。

    • this.$refs.tableNode.toggleRowSelection(item, true);接口请求到数据后,遍历数组,触发勾选项默认勾选
    • 注意点:
      • 数据未完全渲染到表格前,尝试操作选中状态,toggleRowSelection 是失效的。
      • 使用 $nextTick 确保 DOM 更新后再操作选中,此处我就踩坑了,没有用$nextTick ,导致一直失效,好久才反应过来。
  3. pullSort 触发表格拖动排序方法

    • setData 解决 Firefox 浏览器拖拽时的兼容性问题,避免出现禁止拖拽的图标。
    • onStart 拖拽开始前,将选中的数据备份一下。踩坑,因为拖拽过程中重新渲染了表格数据,导致选中状态丢失,大家可测试打印一下,看看是否丢失。
    • onEnd 拖拽结束时的回调函数
      • evt.oldIndex 和 evt.newIndex

        • Sortable.js 提供的拖拽事件参数,表示拖拽前后的位置索引。
      • 数组元素移动逻辑

        • splice(evt.oldIndex, 1)[0]:从原位置删除元素并返回该元素。
        • splice(evt.newIndex, 0, movedItem):将元素插入新位置。
      • this.$nextTick

        • 确保 DOM 更新完成后再操作选中状态,避免因异步渲染导致的行选中失效。
      • 恢复选中状态的逻辑

        • selectedRowsBackup:拖拽前备份的选中行字段(如 [‘field1’, ‘field2’])。

        • this.tableData.find(item => item.field === row):根据 field 找到拖拽后的行对象。

        • toggleRowSelection(targetRow, true):手动设置行选中(需配合 表格 ref)。

  4. submit 提交保存,将排序后的数组保存下来,并且同时保存一下选中状态。

Sortable.js 完整流程图

开始拖拽→ 备份选中行 (onStart)→ 移动数据 (onEnd)→ 等待DOM更新 ($nextTick)→ 遍历备份的选中字段→ 找到新位置的行对象→ 重新选中 (toggleRowSelection)
结束

父组件使用方式

Drawer 抽屉组件 加载子组件设置
	<el-drawer title="列表设置" :visible.sync="listFieldSet.dialogVisible" size="20%" direction="rtl"><listFieldSet ref="listFieldSetRef" @close="listFieldSet.dialogVisible = false"></listFieldSet></el-drawer>
父组件使用
<template><el-table :data="tableData" v-loading="loading" border style="width: 100%" ref="table"><template v-for="(item, index) in listFieldData"><el-table-column v-if="item.isShow" :key="index" :prop="item.field" :label="item.fieldName" width="120"><template slot-scope="scope"><span v-if="item.field === 'proName'">{{ scope.row.project ? scope.row.project.proName : '' }}</span><span v-else>{{ scope.row[item.field] || '' }}</span></template></el-table-column></template><el-table-column label="操作" fixed="right"></el-table-column></el-table>
</template>

使用的场景和方式非常多,上面我是用遍历+判断,正常渲染排序后的列表字段。大家理解后可以灵活应对类似需求

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

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

相关文章

故障扭曲棱镜反射照片效果ps特效滤镜样机 Distorted Mirror Poster Effect

只需单击几下即可执行令人着迷的高质量图像和摄影&#xff01;此照片效果包含智能对象图层&#xff0c;提供完全自定义、易用性和多功能性的工作流程。只需双击其缩略图打开所需的图层&#xff0c;删除占位符镜头&#xff0c;添加图形&#xff0c;保存它&#xff0c;然后观看 P…

基于dify平台批量分析excel格式信息

如何以表格形式批量输入一些信息&#xff0c;然后让大模型以对话应用形式逐条进行推理分析&#xff1f; 这里提供一个分步解决方案&#xff0c;结合 Dify平台功能 和 API调用优化 的思路&#xff0c;既保证效率又降低复杂度&#xff1a; 1. 优先检查 Dify 的「数据集」功能 Di…

CARLA常见技术问题集锦(一)地图与场景构建篇

编者荐语&#xff1a; 在自动驾驶技术加速落地的今天&#xff0c;CARLA 仿真引擎凭借其开源生态与高保真仿真能力&#xff0c;已成为全球开发者构建智能驾驶算法的核心工具之一。随着虚幻引擎 5.5 的全面升级&#xff0c;CARLA 0.10.0 版本实现了视觉革命&#xff1a;Lumen 全…

vue+webpack5(高级配置)

项目地址 基础配置可查看文档 1、devtool 配置 (找到报错位置)2、优化打包速度3、oneOf 每个文件只被一个loader处理4、 include/exclude 处理某些文件或者排除某些文件5、 cache 缓存 &#xff08;提升后面几次的打包速度&#xff09;6、 多进程打包7、减少代码体积 Tree Shak…

JavaWeb——事务管理、AOP

目录 一、事管理 1.开启事务管理日志 2.开启事务管理 3.传播行为 二、AOP 1.通知类型 2.通知顺序 3.切入点表达式 4.连接点 一、事务管理 1.开启事务管理日志 2.开启事务管理 3.传播行为 当一个事务方法被另一个事务方法调用时&#xff0c;这个事物方法应该如何进行事…

okhttp3网络请求

一、使用okhttp3和gson build.gradle ... dependencied {...implementation com.squareup.okhttp3:okhttp:3.9.0implementation com.google.code.gson:gson:2.10.1 }二、响应模型 可根据实际情况进行调整&#xff0c;目前我所需的就是这三个变量 HttpResponseData.java im…

【蓝桥杯每日一题】3.28

&#x1f3dd;️专栏&#xff1a; 【蓝桥杯备篇】 &#x1f305;主页&#xff1a; f狐o狸x "今天熬的夜&#xff0c;会变成明天奖状的闪光点&#xff01;" 目录 一、唯一的雪花 题目链接 题目描述 解题思路 解题代码 二、逛画展 题目链接 题目描述 解题思路 解题代…

【MinIO】Bucket的生命周期管理

&#x1f47b;创作者&#xff1a;丶重明 &#x1f47b;创作时间&#xff1a;2025年3月7日 &#x1f47b;擅长领域&#xff1a;运维 目录 1.ILM使用介绍2.生命周期配置实例 1.ILM使用介绍 对象生命周期管理&#xff08;ILM&#xff09;是现代对象存储系统的核心功能之一&#x…

Android 中隐藏标题栏和状态栏的方法

在Android开发中&#xff0c;隐藏标题栏和状态栏是实现全屏显示的常见需求。 一、隐藏标题栏 1、通过代码隐藏 对于继承自 AppCompatActivity 的 Activty&#xff0c;可在 onCreate() 方法中调用supportRequestWindowFeature 或 getSupportActionBar 方法来隐藏标题栏。 ove…

进程间通信——信号量

进程间通信——信号量 目录 一、基本概念 1.1 概念 1.2 基本操作 1.3 相关函数 1.3.1 semget创建/获取 1.3.2 semop操作信号量 1.3.3 semctl初始化/删除 二、代码操作 2.1 不用PV的 2.2 用PV 的 2.2.1 a.c 2.2.2 b.c 2.2.3 sem.h 2.2.4 sem.c 一、基本概念 1.1…

Linux内核2-TFTP与NFS环境搭建

Uboot&#xff1a;引导程序 初始化硬件设备&#xff0c;初始化c语言环境&#xff0c;为内核加载做准备 zImage:内核文件 rootfs:文件系统&#xff0c;为用户提供一个与硬件设备数据交互的系统 1.TFTP和NFS功能 TFTP:简单文件传输协议网络配置 pc可以下载 2.minicom bootargs…

TDengine 中的命名与边界

简介 本章主要介绍命名的合法字符集和限制规则&#xff0c;这对于正确使用 TDengine&#xff0c;减小报错很重要&#xff0c;这些规则在 SQL 语句中都生效&#xff0c;在使用过程中要注意&#xff0c;避免不必要的错误。 名称命名规则 合法字符&#xff1a;英文字符、数字和…

C++ 中将函数作为参数传递

C 中将函数作为参数传递 1. 通过指针传递函数 函数可以通过传递函数的地址来作为参数传递&#xff1b;简而言之&#xff0c;就是通过指针实现这一点。 示例代码 #include <iostream> using namespace std;// 定义加法和减法函数 #include <iostream> #include …

Vala 编程语言教程-继承

继承‌ 在 Vala 中&#xff0c;一个类可以继承自 ‌一个或零个‌ 其他类。尽管实际开发中通常继承一个类&#xff08;不同于 Java 等语言的隐式继承机制&#xff09;&#xff0c;但 Vala 并不强制要求必须继承。 当定义继承自其他类的子类时&#xff0c;子类的实例与父…

Crypto Architecture Kit简介

HarmonyOS 5.0.3(15) 版本的配套文档&#xff0c;该版本API能力级别为API 15 Release 文章目录 约束与限制能力范围基本概念与相关Kit的关系 Crypto Architecture Kit屏蔽了第三方密码学算法库实现差异的算法框架&#xff0c;提供加解密、签名验签、消息验证码、哈希、安全随机…

交流电机类型及其控制技术

交流电机可分为同步电机和异步电机两大种类&#xff0c;如果电机转子的转速与定子旋转磁场的转速相等&#xff0c;转子与定子旋转磁场在空间同步地旋转&#xff0c;这种电机就称为同步电机。如果电机转子的转速不等于定子旋转磁场的转速&#xff0c;转子与定子旋转磁场在空间旋…

SQL语言分类及命令详解(一)

目录 1. DQL&#xff08;Data Query Language&#xff09;数据查询语言 主要命令&#xff1a; SELECT 2. DDL&#xff08;Data Definition Language&#xff09;数据定义语言 主要命令&#xff1a; CREATE ALTER DROP TRUNCATE&#xff08;清空表数据&#xff0c;保留…

fluent_UDF学习笔记

UDF源代码路径 D:\Program Files\ANSYS Inc\v231\fluent\fluent23.1.0\src关于颗粒反弹速度的计算 /* 通过面法向单位向量计算速度的法向向量、切向向量&#xff0c;再通过法向、切向恢复系数重新计算反弹速度*//* Compute normal velocity.将颗粒速度向面法线方向投影&#x…

Go 语言标准库中sort模块详细功能介绍与示例

Go语言的 sort 模块提供了对切片和自定义数据结构的排序功能&#xff0c;支持基本类型排序、自定义排序规则、稳定排序和二分查找。以下是 sort 模块的核心方法及示例说明&#xff1a; 1. 基本类型排序 sort.Ints、sort.Float64s、sort.Strings 直接对基本类型的切片进行排序…

第十六届蓝桥杯模拟二(串口通信)

由硬件框图可以知道我们要配置LED 和按键 一.LED 先配置LED的八个引脚为GPIO_OutPut,锁存器PD2也是,然后都设置为起始高电平,生成代码时还要去解决引脚冲突问题 二.按键 按键配置,由原理图按键所对引脚要GPIO_Input 生成代码,在文件夹中添加code文件夹,code中添加fun.…