Sortable实现拖拽节点列表操作
安装
npm install sortablejs --save
<script src="../../js/Sortable.min.js"></script>
引用
import Sortable from "sortablejs";
使用
<template> <div class="table"> <el-table ref="dragTable" :data="tableData" :key="key" border :row-class-name="tableRowClassName" > <el-table-column v-for="col in tableHeaderData" :key="col.id" :prop="col.prop" :label="col.label" > <template v-if="col.template"> <el-button class="move" type="text" size="small">拖 拽</el-button> </template> </el-table-column> </el-table> </div> </template> <script> import Sortable from "sortablejs"; export default { data() { return { // 表头数据 tableHeaderData: [ { label: "日期", prop: "date" }, { label: "姓名", prop: "name" }, { label: "地址", prop: "address" }, { label: "操作", prop: "", template: true }, ], // 表格数据 tableData: [ { id: "1", name: "姓名_1", date: "日期-11-11", address: "地址_1", }, { id: "2", name: "姓名_2_不可拖拽", date: "日期-22-22", address: "地址_2_不可拖拽", disabled: true, }, { id: "3", name: "姓名_3", date: "日期-33-33", address: "地址_3", }, { id: "4", name: "姓名_4", date: "日期-44-44", address: "地址_4", }, { id: "5", name: "姓名_5", date: "5555-55-55", address: "地址_5", }, ], key: 1, }; }, methods: { // 行拖拽 initSortableRow() { // 获取表格row的父节点 const eleRow = this.$refs.dragTable.$el.querySelector( ".el-table__body > tbody" ); // 创建行拖拽实例 const dragTableRow = Sortable.create(eleRow, { animation: 150, //动画 handle: ".move", //指定拖拽目标,点击此目标才可拖拽元素(此例中设置操作按钮拖拽) filter: ".disabled", //指定不可拖动的类名(el-table中可通过row-class-name设置行的class) dragClass: "dragClass", //设置拖拽样式类名 ghostClass: "ghostClass", //设置拖拽停靠样式类名 chosenClass: "chosenClass", //设置选中样式类名 // 开始拖动事件 onStart: () => { console.log("开始拖动"); }, // 结束拖动事件 onEnd: (e) => { console.log( "结束拖动", `拖动前索引${e.oldIndex}---拖动后索引${e.newIndex}` ); }, }); }, // 列拖拽 initSortableCol() { // 获取表格col的父节点 const eleCol = this.$refs.dragTable.$el.querySelector( ".el-table__header-wrapper tr" ); // 创建列拖拽实例 const dragTableCol = Sortable.create(eleCol, { animation: 150, dragClass: "dragClass", ghostClass: "ghostClass", chosenClass: "chosenClass", // 结束拖动事件 onEnd: (e) => { // 拖拽结束之后通过修改tableHeaderData顺序改变表头顺序 const dragHeaderCopy = this.tableHeaderData[e.oldIndex]; // 备份当前拖拽的表头 this.tableHeaderData.splice(e.oldIndex, 1); //把当前拖动的表头去掉 this.tableHeaderData.splice(e.newIndex, 0, dragHeaderCopy); //把当前拖拽的表头添加到新位置 /** * 在做列拖拽功能时发现问题:表头位置错乱,但是内容列正常 * 于是我给el-table绑定key,每次拖拽结束改变key触发表格重新渲染。 * 但引出新的问题:表格重渲拖拽事件丢失,导致之后无法拖拽 * 于是我在表格重渲之后重新调用拖拽方法创建拖拽实例,功能正常了 * 如果有更好的解决方案,欢迎评论、私信交流,谢谢 * **/ this.key += 1; this.$nextTick(() => { this.initSortableRow(); this.initSortableCol(); }); console.log(dragHeaderCopy, "结束拖动", this.tableHeaderData); }, }); }, // 设置表格row的class(此例中通过设置class来配合拖拽属性filter设置某行不可拖拽) tableRowClassName({ row }) { if (row.disabled) { return "disabled"; } return ""; }, }, mounted() { // 行拖拽 this.initSortableRow(); // 列拖拽 this.initSortableCol(); }, }; </script> <style lang='scss'> // 拖拽 .dragClass { background: rgba($color: #41c21a, $alpha: 0.5) !important; } // 停靠 .ghostClass { background: rgba($color: #6cacf5, $alpha: 0.5) !important; } // 选择 .chosenClass:hover > td { background: rgba($color: #f56c6c, $alpha: 0.5) !important; } </style>