项目需求
iview表单实现拖拽排序。并将排序后数据保存至后台。
实现思路
首先,要在 Table 标签上设置draggable="true"属性,开启拖拽功能
然后,添加 @on-drag-drop="DragTableSort"方法,实现拖拽逻辑,DragTableSort方法返回置换的两行数据索引
DragTableSort 方法里具体的逻辑可以根据自己的情况自定义,这里记录了2种实现方式
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、拖拽实现方案(一)
根据DragTableSort 返回的索引,实现两条数据的index和orderid的互换,然后保存至后台,并未实现真正意义的排序。
代码如下(示例):
<template>
<Table
border
:columns="columns"
:data="data"
:draggable="true"
@on-drag-drop="DragTableSort"
>
</Table>
</template>
<script>
export default {
data() {
return {
columns: [
{
title: "code",
key: "code",
},
{
title: "name",
key: "name",
},
],
data: [
{
code: "01",
name: "名称1",
orderId: 1,
},
{
code: "02",
name: "名称2",
orderId: 2,
},
{
code: "03",
name: "名称3",
orderId: 3,
},
{
code: "04",
name: "名称4",
orderId: 4,
},
{
code: "05",
name: "名称5",
orderId: 5,
},
{
code: "06",
name: "名称6",
orderId: 6,
},
],
};
},
methods: {
DragTableSort(oldIndex, newIndex) {
/* 前端互换2条数据index 和 orderid */
oldIndex = parseInt(oldIndex);
newIndex = parseInt(newIndex);
let oldData = this.data[oldIndex];
let oldData_orderId = this.data[newIndex].orderId;
this.data[newIndex].orderId = oldData.orderId;
oldData.orderId = oldData_orderId;
this.data.splice(oldIndex, 1, this.data[newIndex]);
this.data.splice(newIndex, 1, oldData);
//调用接口保存 path:接口地址 old:原始位置 new:新位置
this.$store
.dispatch("fn_OrderTable", {
path: this.$path.tagSaveOrUpdate,
params: {
old: this.data[oldIndex],
new: this.data[newIndex],
},
})
.then((res) => {
this.$Message.success("保存成功!");
}).catch((err) => {
this.$Message.error("保存失败!");
})
},
},
};
</script>
fn_OrderTable({ state, dispatch }, { path, params }) {
let p1 = new Promise((resolve, reject) => {
dispatch('authPostRequest', { url: path, params: params.old }).then(resp => {
if (resp.success) {
resolve('成功了')
}
})
})
let p2 = new Promise((resolve, reject) => {
dispatch('authPostRequest', { url: path, params: params.new }).then(resp => {
if (resp.success) {
resolve('成功了')
}
})
})
return Promise.all([p1, p2])
}
二、拖拽实现方案(二)
由于方案一不符合项目需求,在方案一基础进行了优化,根据DragTableSort 返回的索引,判断拖拽方向,如果是向下拖拽,则下边的数据依次向上移动;如果向上拖拽,上边的数据依次向下移动。
排序方式的处理:由于后台返回的列表数据orderid不是连续的(例如:3,5,14,17),拖拽前先记录一下排序oldSortArr,排序后再次对列表的orderid重新进行赋值。
代码如下(示例):
<template>
<Table
border
:columns="columns"
:data="data"
:draggable="true"
@on-drag-drop="DragTableSort"
>
</Table>
</template>
<script>
export default {
data() {
return {
columns: [
{
title: "code",
key: "code",
},
{
title: "name",
key: "name",
},
],
data: [
{
code: "01",
name: "名称1",
orderId: 1,
},
{
code: "02",
name: "名称2",
orderId: 2,
},
{
code: "03",
name: "名称3",
orderId: 3,
},
{
code: "04",
name: "名称4",
orderId: 4,
},
{
code: "05",
name: "名称5",
orderId: 5,
},
{
code: "06",
name: "名称6",
orderId: 6,
},
],
};
},
methods: {
DragTableSort(first, end) {
//调用公共方法 path:接口地址 data:列表 first:置换前 end:置换后
this.$store
.dispatch("fn_OrderTable", {
path: this.$path.tagSaveOrUpdate,
params: {
data: this.data,
first: first,
end: end,
},
})
.then((res) => {
this.$Message.success("保存成功!");
})
.catch((err) => {
this.$Message.error("保存失败!");
});
},
},
};
</script>
fn_OrderTable({ state, dispatch }, { path, params }) {
//记录拖拽前排序
let oldSortArr = params.data.map((item, index) => {
return item.orderId;
});
let first = parseInt(params.first);
let end = parseInt(params.end);
let tmp = params.data[first];
//向下拖拽,则下边的数据依次向上移动
if (first < end) {
for (var i = first + 1; i <= end; i++) {
params.data.splice(i - 1, 1, params.data[i]);
}
params.data.splice(end, 1, tmp);
}
//向上拖拽,上边的数据依次向下移动
if (first > end) {
for (var i = first; i > end; i--) {
params.data.splice(i, 1, params.data[i - 1]);
}
params.data.splice(end, 1, tmp);
}
//orderId重置排序
params.data.forEach((e, index) => {
e.orderId = oldSortArr[index];
});
//此处过滤保存到服务端的数据项
let OrderArr = []
if (first < end) {
OrderArr = params.data.slice(first, end + 1)
}
if (first > end) {
OrderArr = params.data.slice(end, first + 1)
}
var promiseArray = [];
for (var i = 0; i < OrderArr.length; i++) {
promiseArray.push(new Promise(function (resolve, reject) {
dispatch('authPostRequest', { url: path, params: OrderArr[i] }).then(resp => {
if (resp.success) {
resolve('成功了')
}
})
}))
}
return Promise.all(promiseArray)
}
总结
由于在增加列表拖拽前项目已经基本开发完成了,为减少后台开发者的工作量,采用现有单条数据的保存接口,因此保存至后台的时候进行了多次接口请求。
还可进一步优化