vue基于SortableJS实现表格拖动排序
Posted 水星记_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue基于SortableJS实现表格拖动排序相关的知识,希望对你有一定的参考价值。
前言
大家都知道element中的树形控件要想拖动排序,我们只需要设置其draggable属性即可,但是在表格中要如何实现该操作呢?element官网中并没有提到,但是我们可以基于一些第三方的插件实现,今天给大家分享一个功能强大的javascript拖拽库—SortableJS。
安装
npm install sortablejs --save
cnpm install sortablejs --save
引入
import Sortable from 'sortablejs'
使用
el-table
中必须加上 row-key="id"
,否则可能会导致排序不成功。原因是因为 vue
的加载循环机制,在进行删除时,一定要添加 key
,跟使用 v-for
循环一样都需要添加绑定 key
值。
基础表格拖动排序
源码如下
<template>
<div>
<!-- 表格控件 -->
<el-table :data="tableData" ref="tableNode" border highlight-current-row row-key="id">
<el-table-column prop="name" label="姓名" align="center"></el-table-column>
<el-table-column prop="sex" label="性别" align="center"></el-table-column>
<el-table-column prop="age" label="年龄" align="center"></el-table-column>
<el-table-column prop="address" label="地址" align="center"></el-table-column>
</el-table>
</div>
</template>
<script>
import Sortable from "sortablejs"; //引入下载的插件
export default
data()
return
// 模拟数据
tableData: [
id: "1",
name: "第一",
sex: "男",
age: "12",
address: "北京",
,
id: "2",
name: "第二",
sex: "男",
age: "23",
address: "上海",
,
id: "3",
name: "第三",
sex: "女",
age: "21",
address: "广州",
,
id: "4",
name: "第四",
sex: "女",
age: "12",
address: "深圳",
,
],
;
,
mounted()
this.pullSort(); //声明表格拖动排序方法
,
methods:
//表格拖动排序方法
pullSort()
// 通过ref获取Dom节点
const el = this.$refs.tableNode.$el.querySelectorAll(
".el-table__body-wrapper > table > tbody"
)[0];
this.sortable = Sortable.create(el,
animation: 600, //拖拽动画(毫秒)
setData: function (dataTransfer)
dataTransfer.setData("Text", "");
,
// 结束拖拽
onEnd: (e) =>
//e.oldIndex为拖动一行原来的位置;e.newIndex为拖动后新的位置
const oldRow = this.tableData[e.oldIndex]; // 移动元素集合
const newRow = this.tableData[e.newIndex]; // 新的元素集合
console.log(oldRow, "移动元素集合");
console.log(newRow, "新的元素集合");
// 调用接口传参即可
,
);
,
,
;
</script>
树形结构表格拖动排序
树形表格拖动不同于简单的表格拖动,我们要考虑到树形表格每一层的层级,如果返回的数据没有层级,我们需要给树形的数据去添加每一层的层级,其次,我们还得将树形表格数据转化为平铺数据在进行拖动,如果不转换的话,后面拖动的位置就是不对的,就会出错了,下面看代码实例。
源码如下
<template>
<div>
<!-- 表格树控件 -->
<el-table :data="tableData" ref="tableNode" border highlight-current-row row-key="id">
<el-table-column prop="label" label="模块" align="center"></el-table-column>
</el-table>
</div>
</template>
<script>
import Sortable from "sortablejs"; //引入下载的插件
// import treeSort from "@/api/system";//引入接口方法
export default
data()
return
// 模拟数据,实际情况根据后台返回数据调整
tableData: [
id: "2619",
label: "菜单一",
parentId: "79f32a6fdbaisdaishdadhsd0b3540e17a0a",
,
id: "4d1dd2a5wd3s2f1a5fd1as8f6869dc7b",
label: "菜单二",
parentId: "79f32a6fdbaisdaishdadhsd0b3540e17a0a",
children: [
id: "4006",
label: "A-1",
parentId: "4d1dd2a5wd3s2f1a5fd1as8f6869dc7b",
,
],
,
id: "52cqw8r7f4a65s3d1a5f4s65a3d2w1507f93",
label: "菜单三",
parentId: "79f32a6fdbaisdaishdadhsd0b3540e17a0a",
children: [
id: "4005",
label: "B-1",
parentId: "52cqw8r7f4a65s3d1a5f4s65a3d2w1507f93",
,
],
,
id: "66d5a4s13d2c1as5f4a6w5s13das12a89",
label: "菜单四",
parentId: "79f32a6fdbaisdaishdadhsd0b3540e17a0a",
children: [
id: "3033",
label: "C-1",
parentId: "66d5a4s13d2c1as5f4a6w5s13das12a89",
,
id: "3034",
label: "C-2",
parentId: "66d5a4s13d2c1as5f4a6w5s13das12a89",
,
],
,
],
activeRows: [], // 转换为列表的数据
;
,
mounted()
this.pullSort(); //声明表格拖动排序方法
,
methods:
//拖拽排序
pullSort()
const tbody = this.$refs.tableNode.$el.querySelectorAll(".el-table__body-wrapper > table > tbody")[0];
const _this = this;//防止this指向问题
Sortable.create(tbody,
animation: 600,
onMove( dragged, related )
_this.$set(_this,"tableData",_this.arrayTreeSetLevel(_this.tableData)); // 树形结构数据添加level
_this.activeRows = _this.treeToTile(_this.tableData); // 把树形的结构转为列表再进行拖拽
,
onEnd(e)
//e.oldIndex为拖动一行原来的位置,e.newIndex为拖动后新的位置
if (e.oldIndex !== e.newIndex)
const oldRow = _this.activeRows[e.oldIndex]; // 移动元素
const newRow = _this.activeRows[e.newIndex]; // 新的元素
// level 当前层级 parentId 父级id
if (oldRow.level != newRow.level || oldRow.parentId != newRow.parentId)
//不能跨级拖拽
_this.$message(
message: "只允许同级拖拽",
type: "warning",
);
_this.tableData = [];//清空列表数据
// _this.getTableTree();//调用列表接口
return false;
else
// // 接口参数
// let data =
// previousId: oldRow.id,
// lastId: newRow.id,
// ;
// // 请求接口
// treeSort(data).then((res) =>
// if (res.code == "10000")
// _this.tableData = [];//清空列表数据
// _this.getTableTree();//调用列表接口
// _this.$message(
// message: res.msg,
// type: "success",
// );
//
// );
,
);
,
// 给树形的数据去添加每一层的层级
arrayTreeSetLevel(array, levelName = "level", childrenName = "children")
if (!Array.isArray(array))
return [];
const recursive = (array, level = 0) =>
level++;
return array.map((v) =>
v[levelName] = level;
const child = v[childrenName];
if (child && child.length)
recursive(child, level);
return v;
);
;
return recursive(array);
,
// 将树数据转化为平铺数据
treeToTile(treeData, childKey = "children")
const arr = [];
const expanded = (data) =>
if (data && data.length > 0)
data
.filter((d) => d)
.forEach((e) =>
arr.push(e);
expanded(e[childKey] || []);
);
;
expanded(treeData);
return arr;
,
,
;
</script>
总结
SortableJS
为开发者提供了多种拖动效果,单列表、多列表、嵌套排序等等都不在话下,大家感兴趣的话可以去官网查看: SortableJS 中文网
拓展
有关于 element 中树形控件(el-tree)如何实现拖动效果,大家可移步博主另一篇文章(vue基于element树形控件实现上下拖拽)
以上是关于vue基于SortableJS实现表格拖动排序的主要内容,如果未能解决你的问题,请参考以下文章