Vue + Element UI el-table + sortablejs 行、列拖拽排序

实现Element UI中的el-table表格组件的行和列的拖拽排序

使用 Vue3 + Element Plus UI + sortablejs

安装sortablejs

pnpm install sortablejs

行拖拽

基本实现

效果
在这里插入图片描述

<script setup>
import { onMounted, ref } from "vue";
import Sortable from "sortablejs";const tableData = ref([{id: 1,date: "2016-05-02",name: "王小虎111",age: 21,address: "上海市普陀区金沙江路 1518 弄",},{id: 2,date: "2016-05-04",name: "王小虎222",age: 22,address: "上海市普陀区金沙江路 1517 弄",},{id: 3,date: "2016-05-01",name: "王小虎333",age: 23,address: "上海市普陀区金沙江路 1519 弄",},{id: 4,date: "2016-05-03",name: "王小虎444",age: 24,address: "上海市普陀区金沙江路 1516 弄",},{id: 5,date: "2016-05-08",name: "王小虎555",age: 25,address: "上海市普陀区金沙江路 1518 弄",},
]);onMounted(() => {rowDrop();
});/*** 行拖拽排序*/
function rowDrop() {// 要侦听拖拽响应的DOM对象const tbody = document.querySelector(".el-table__body-wrapper tbody");const data = tableData.value;Sortable.create(tbody, {// handle: ".el-icon-rank",ghostClass: "target-row-class",// 结束拖拽后的回调函数onEnd({ newIndex, oldIndex }) {// 将oldIndex位置的数据删除并取出,oldIndex后面位置的数据会依次前移一位const currentRow = data.splice(oldIndex, 1)[0];// 将被删除元素插入到新位置(currRow表示上面的被删除数据)data.splice(newIndex, 0, currentRow);},});
}
</script><template><el-tableref="table":data="tableData"style="width: 100%"borderrow-key="id"><el-table-column prop="date" label="日期" /><el-table-column prop="name" label="姓名" /><el-table-column prop="age" label="年龄" /><el-table-column prop="address" label="地址" /><!--<el-table-column align="center" width="55">--><!--  <i class="el-icon-rank" />--><!--</el-table-column>--></el-table>
</template><style scoped lang="less">
.el-table {::v-deep {.target-row-class {background: #f0f9eb;}}
}
</style>

禁止某几行拖拽

效果
在这里插入图片描述

<script setup>
import { onMounted, ref } from "vue";
import Sortable from "sortablejs";const tableData = ref([{id: 1,date: "2016-05-02",name: "王小虎111",age: 21,address: "上海市普陀区金沙江路 1518 弄",},{id: 2,date: "2016-05-04",name: "王小虎222",age: 22,address: "上海市普陀区金沙江路 1517 弄",},{id: 3,date: "2016-05-01",name: "王小虎333",age: 23,address: "上海市普陀区金沙江路 1519 弄",},{id: 4,date: "2016-05-03",name: "王小虎444",age: 24,address: "上海市普陀区金沙江路 1516 弄",},{id: 5,date: "2016-05-08",name: "王小虎555",age: 25,address: "上海市普陀区金沙江路 1518 弄",},
]);onMounted(() => {rowDrop();
});/*** 行拖拽排序*/
function rowDrop() {// 要侦听拖拽响应的DOM对象const tbody = document.querySelector(".el-table__body-wrapper tbody");const data = tableData.value;Sortable.create(tbody, {// handle: ".el-icon-rank",ghostClass: "target-row-class",// 匹配的元素将不会触发拖动filter: ".filtered",// 拖拽移动事件,返回false取消移动onMove: function ({ related }) {return related.className.indexOf("filtered") === -1;},// 结束拖拽后的回调函数onEnd({ newIndex, oldIndex }) {// 将oldIndex位置的数据删除并取出,oldIndex后面位置的数据会依次前移一位const currentRow = data.splice(oldIndex, 1)[0];// 将被删除元素插入到新位置(currRow表示上面的被删除数据)data.splice(newIndex, 0, currentRow);},});
}// 设置ID为1和5的行禁止拖拽
function tableRowClassName({ row, rowIndex }) {const freezeList = [1, 5];return freezeList.includes(row.id) ? "filtered" : "";
}
</script><template><el-tableref="table":data="tableData"style="width: 100%"borderrow-key="id":row-class-name="tableRowClassName"><el-table-column prop="date" label="日期" /><el-table-column prop="name" label="姓名" /><el-table-column prop="age" label="年龄" /><el-table-column prop="address" label="地址" /><!--<el-table-column align="center" width="55">--><!--  <i class="el-icon-rank" />--><!--</el-table-column>--></el-table>
</template><style scoped lang="less">
.el-table {::v-deep {.target-row-class {background: #f0f9eb;}// 禁止拖拽行背景色.filtered {background-color: #1db1e7 !important;}}
}
</style>

列拖拽

基本实现

效果
在这里插入图片描述

<script setup>
import { onMounted, ref } from "vue";
import Sortable from "sortablejs";const columns = ref([{ label: "日期", prop: "date" },{ label: "姓名", prop: "name" },{ label: "年龄", prop: "age" },{ label: "地址", prop: "address" },
]);const tableData = ref([{id: 1,date: "2016-05-02",name: "王小虎111",age: 21,address: "上海市普陀区金沙江路 1518 弄",},{id: 2,date: "2016-05-04",name: "王小虎222",age: 22,address: "上海市普陀区金沙江路 1517 弄",},{id: 3,date: "2016-05-01",name: "王小虎333",age: 23,address: "上海市普陀区金沙江路 1519 弄",},{id: 4,date: "2016-05-03",name: "王小虎444",age: 24,address: "上海市普陀区金沙江路 1516 弄",},{id: 5,date: "2016-05-08",name: "王小虎555",age: 25,address: "上海市普陀区金沙江路 1518 弄",},
]);onMounted(() => {columnDrop();
});/*** 列拖拽排序*/
function columnDrop() {// 要侦听拖拽响应的DOM对象const wrapperTr = document.querySelector(".el-table__header-wrapper tr");Sortable.create(wrapperTr, {animation: 180,delay: 0,onEnd({ newIndex, oldIndex }) {const draggedItem = columns.value.splice(oldIndex, 1)[0];columns.value.splice(newIndex, 0, draggedItem);},});
}
</script><template><el-tableref="table":data="tableData"style="width: 100%"borderrow-key="id"><el-table-columnv-for="(column, index) in columns":key="index":prop="column.prop":label="column.label"/></el-table>
</template>

禁止某几行拖拽

效果
在这里插入图片描述

<script setup>
import { onMounted, ref } from "vue";
import Sortable from "sortablejs";const columns = ref([{ label: "日期", prop: "date" },{ label: "姓名", prop: "name", draggable: true },{ label: "年龄", prop: "age", draggable: true },{ label: "地址", prop: "address" },
]);const columnsDrop = ref([{ label: "日期", prop: "date" },{ label: "姓名", prop: "name" },{ label: "年龄", prop: "age" },{ label: "地址", prop: "address" },
]);const tableData = ref([{id: 1,date: "2016-05-02",name: "王小虎111",age: 21,address: "上海市普陀区金沙江路 1518 弄",},{id: 2,date: "2016-05-04",name: "王小虎222",age: 22,address: "上海市普陀区金沙江路 1517 弄",},{id: 3,date: "2016-05-01",name: "王小虎333",age: 23,address: "上海市普陀区金沙江路 1519 弄",},{id: 4,date: "2016-05-03",name: "王小虎444",age: 24,address: "上海市普陀区金沙江路 1516 弄",},{id: 5,date: "2016-05-08",name: "王小虎555",age: 25,address: "上海市普陀区金沙江路 1518 弄",},
]);// 定义变量来记录固定列的class名
const fixedColumnClass = "filtered";onMounted(() => {columnDrop();
});function setHeaderCellClass({ column }) {const columnLabels = columns.value.filter((column) => column.draggable).map((column) => column.label);return !columnLabels.includes(column.label) ? fixedColumnClass : "";
}/*** 列拖拽排序*/
function columnDrop() {// 要侦听拖拽响应的DOM对象const wrapperTr = document.querySelector(".el-table__header-wrapper tr");Sortable.create(wrapperTr, {animation: 180,delay: 0,ghostClass: "target-row-class",filter: `.${fixedColumnClass}`,// filter: (event, item) => {//   // 也可以根据item的类名、id或其他属性来决定是否应该被排除//   return !item.classList.contains("draggable");// },onMove: function ({ related }) {return related.className.indexOf(fixedColumnClass) === -1;},onEnd({ newIndex, oldIndex }) {const draggedItem = columnsDrop.value.splice(oldIndex, 1)[0];columnsDrop.value.splice(newIndex, 0, draggedItem);},});
}
</script><template><el-tableref="table":data="tableData"style="width: 100%"borderrow-key="id":header-cell-class-name="setHeaderCellClass"><el-table-columnv-for="(column, index) in columns":key="column.prop":prop="columnsDrop[index].prop":label="column.label"/></el-table>
</template><style scoped lang="less">
.el-table {::v-deep {.target-row-class {background: #f0f9eb;}.filtered {background-color: #1db1e7 !important;}}
}
</style>

封装Vue指令

未完待续

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

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

相关文章

Elasticsearch(四)

是这样的前面的几篇笔记&#xff0c;感觉对我没有形成知识体系&#xff0c;感觉乱糟糟的&#xff0c;只是大概的了解了一些基础知识&#xff0c;仅此而已&#xff0c;而且对于这技术栈的学习也是为了在后面的java开发使用&#xff0c;但是这里的API学的感觉有点乱&#xff01;然…

排序算法---堆排序

原创不易&#xff0c;转载请注明出处。欢迎点赞收藏~ 堆排序&#xff08;Heap Sort&#xff09;是一种基于二叉堆数据结构的排序算法。它将待排序的元素构建成一个最大堆&#xff08;或最小堆&#xff09;&#xff0c;然后逐步将堆顶元素与堆的最后一个元素交换位置&#xff0c…

Mac电脑到手后的配置

一、Homebrew 1、Homebrew安装 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 桌面的Old_Homebrew文件夹&#xff0c;没有你需要的可以删除。 2、Homebrew卸载 /bin/zsh -c "$(curl -fsSL https://gitee.com/c…

前端实现支付跳转以及回跳

// 支付地址 const baseURL http://pcapi-xiaotuxian-front-devtest.itheima.net/ const backURL http://127.0.0.1:5173/paycallback const redirectUrl encodeURIComponent(backURL) const payUrl ${baseURL}pay/aliPay?orderId${route.query.id}&redirect${redirec…

MPLS VPN功能组件(3)

私网标签分配 通过MPBGP为VPNv4路由分配内层标签 PE从CE接收到IPv4路由后&#xff0c;对该路由加上相应VRF的RD&#xff08;RD手动配置&#xff09;&#xff0c;使其成为一条VPNV4路由&#xff0c;然后在路由通告中更改下一跳属性为自己&#xff0c;通常是自己的Loopback地址…

SpringSecurity+OAuth2权限管理实战

Spring Security快速入门 官方文档&#xff1a; Spring Security :: Spring Security 功能&#xff1a; 身份认证&#xff08;authentication&#xff09; 授权&#xff08;authorization&#xff09; 防御常见攻击&#xff08;protection against common attacks&#xff…

[Java][算法 双指针]Day 02---LeetCode 热题 100---04~07

LeetCode 热题 100---04~07 第一题&#xff1a;移动零 思路 找到每一个为0的元素 然后移到数组的最后 但是需要注意的是 要在给定的数组原地进行修改 并且其他非零元素的相对顺序不能改变 我们采用双指针法 定义两个指针i和j i和j一开始分别都在0索引位置 然后判断j所…

MQTT 服务器(emqx)搭建及使用

推荐阅读&#xff1a; MQTT 服务器(emqx)搭建及使用 - 哔哩哔哩 (bilibili.com) 一、EMQX 服务器搭建 1、下载EMQX https://www.emqx.com/zh/try?productbroker 官方中文手册&#xff1a; EMQX Docs 2、安装使用 1、该软件为绿色免安装版本&#xff0c;解压缩后即安装完…

第三百一十五回

文章目录 1. 概念介绍2. 基本用法3. 补充用法4. 内容总结 我们在上一章回中介绍了"再谈ListView中的分隔线"&#xff0c;本章回中将介绍showMenu的用法.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在第一百六十三回中介绍了showMenu相关的内容…

商业智能(BI)数据分析、挖掘概念

商业智能&#xff08;BI&#xff09;数据分析挖掘概念 一、商业智能&#xff08;BI&#xff09;数据分析挖掘概念 数据挖掘目前在各类企业和机构中蓬勃发展。因此我们制作了一份此领域常见术语总结。 1.分析型客户关系管理&#xff08;Analytical CRM/aCRM 用于支持决策&…

基于华为云欧拉操作系统(HCE OS)单节点容器化部署(Prometheus、node-exporter、Grafana)应用性能监控平台

写在前面 博文内容为 华为云欧拉操作系统入门级开发者认证(HCCDA – Huawei Cloud EulerOS)实验笔记整理认证地址&#xff1a;https://edu.huaweicloud.com/certificationindex/developer/9bf91efb086a448ab4331a2f53a4d3a1内容涉及&#xff0c;HCE OS 容器化部署(Prometheus、…

Jumserver 安装

一、Jumserver 官网地址 Jumserver官网地址 二、Jumserver的基本概率 1、4a概率 首先&#xff0c;堡参机提供了运维安全审计的4A规范 Authentication: 身份鉴别&#xff0c;防止身份冒用和复用(开发10人&#xff0c;测试5人&#xff0c;运维2人&#xff09; Authorizatton:授…