实现表格行列拖拽-【sortablejs】
背景
有的时候我们需要前端来实现行和列的拖拽,把想要看的内容往前提,
效果图
代码
- 为el-table设置
row-key
,如不设置会导致拖拽顺序紊乱 - 行拖拽,通过获取拖拽前后移动行的索引,更新表格数据
- 列拖拽,注意:这块需要多写一个列数组!---这块不是很懂为什么,但是如果不增加列数组去操作的话是达不到列拖拽的效果
<template>
<div class="app">
<h1>实现表格行列拖拽</h1>
<el-table
class="drag-table"
row-key="id"
:data="tableData"
border
style="width: 100%"
>
<el-table-column
v-for="(item, index) in columns"
:key="item.prop"
:prop="dragCols[index].prop"
:label="item.label"
></el-table-column>
</el-table>
<div class="data-box">
<pre>
<h3>columns</h3>
{{ columns }}
</pre>
<hr />
<pre>
<h3>dragCols</h3>
{{ dragCols }}
</pre>
</div>
</div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import Sortable from "sortablejs";
import Mock from "mockjs";
// 模拟表格数据
const tableData = ref([]);
const ret = Mock.mock({
"result|10-20": [
{
id: "@guid",
"number|+1": 1,
date: "@date",
name: "@name",
email: "@email",
address: "@csentence(8,15)",
},
],
});
tableData.value = ret.result;
onMounted(() => {
setRowDrag();
setColDrag();
});
// 1. 设置行拖拽
const setRowDrag = () => {
// 1.1 获取tbody元素
const tbody = document.querySelector(".drag-table .el-table__body tbody");
Sortable.create(tbody, {
onEnd: ({ newIndex, oldIndex }) => {
// 1.2 获取拖拽前后的索引,然后更新表格数据
const currentRow = tableData.value.splice(oldIndex, 1)[0];
tableData.value.splice(newIndex, 0, currentRow);
},
});
};
const columns = ref([
{
label: "序号1",
prop: "number",
},
{
label: "日期2",
prop: "date",
},
{
label: "姓名3",
prop: "name",
},
{
label: "邮件4",
prop: "email",
},
{
label: "地址4",
prop: "address",
},
]);
const dragCols = ref([
{
label: "序号1",
prop: "number",
},
{
label: "日期2",
prop: "date",
},
{
label: "姓名3",
prop: "name",
},
{
label: "邮件4",
prop: "email",
},
{
label: "地址4",
prop: "address",
},
]);
// 2. 设置列拖拽
const setColDrag = () => {
// 2.1 获取元素
const tr = document.querySelector(".drag-table .el-table__header-wrapper tr");
Sortable.create(tr, {
animation: 180,
delay: 0,
onEnd: (e) => {
// 注意:这里需要定义对一个相同的列
const oldColumn = dragCols.value[e.oldIndex];
dragCols.value.splice(e.oldIndex, 1);
dragCols.value.splice(e.newIndex, 0, oldColumn);
},
});
};
</script>
<style lang="less" scoped>
.data-box {
position: fixed;
right: 0;
top: 0;
width: 500px;
background-color: orange;
h3 {
text-align: center;
}
}
</style>