1.效果:
拖拽前:
拖拽后:
文章来源:https://www.toymoban.com/news/detail-659243.html
2.实现:
<template>
<a-card :bordered="false">
<a-table bordered :columns="columns" :data-source="data" :customRow="customRow" :pagination="pagination"
@change="tableChange">
<template v-slot:action>
<a href="javascript:;" style="cursor:move">拖拽排序</a>
</template>
</a-table>
</a-card>
</template>
<script>
import Vue from "vue";
import VueDraggableResizable from "vue-draggable-resizable";
// 可拖拽表格
// "vue-draggable-resizable": "2.1.0" //=>需要的话记得安装
// "ant-design-vue": "^1.5.5"
Vue.component("vue-draggable-resizable", VueDraggableResizable);
import { mapState } from 'vuex';
import { mixinDevice } from '@/utils/mixin'
import '@/assets/less/TableExpand.less'
import { getAction, deleteAction, putAction, putActions, postAction, postActions, httpAction, downFile, uploadAction } from '@/api/manage' //二次封装的接口方法
export default {
name: "queueInfoList",
mixins: [mixinDevice],
data() {
// this.components = {//实现伸缩列=>不需要的话a-table去除:components="components"
// header: {
// cell: (h, props, children) => {
// const { key, ...restProps } = props;
// console.log("ResizeableTitle", key);
// const col = this.columns.find(col => {
// const k = col.dataIndex || col.key;
// return k === key;
// });
// if (!col || !col.width) {
// return h("th", { ...restProps }, [...children]);
// }
// const dragProps = {
// key: col.dataIndex || col.key,
// class: "table-draggable-handle",
// attrs: {
// w: 10,
// x: col.width,
// z: 1,
// axis: "x",
// draggable: true,
// resizable: false
// },
// on: {
// dragging: (x, y) => {
// console.log(x, y);
// col.width = Math.max(x, 1);
// }
// }
// };
// const drag = h("vue-draggable-resizable", { ...dragProps });
// return h("th", { ...restProps, class: "resize-table-th" }, [
// ...children,
// drag
// ]);
// }
// }
// };
return {
sourceObj: null,
targetObj: null,
dragStartIndex: '',
queryParam: {
bankPositon: '',//装卸位
carNumber: '',//车号
varietyName: '',//货品
deptId: '',
stationId: '',
pageNo: '1',
pageSize: '10',
isInQueue: '1',// 是否排队中。1=是,0=否
},
url: {
list: '/kd/queueInfo/list',
queueInfoSort: "/kd/queueInfo/editSort",// 排队列表-拖拽排序
},
columns: [
{
title: "序号",
align: "center",
dataIndex: "queueNo",
sorter: true,
},
{
title: "id",
align: "center",
dataIndex: "id",
sorter: true,
},
{
title: "库位",
align: "center",
dataIndex: "bankPositon",
sorter: true,
},
{
title: "货品",
align: "center",
dataIndex: "varietyName",
sorter: true,
},
{
title: "车牌号码",
align: "center",
dataIndex: "carNumber",
sorter: true,
},
{
title: "状态",
sorter: true,
align: "center",
dataIndex: "status",
// status 状态(1:等待装车,2正在装车,3装车完成)
customRender: function (text) {
return !text ? "" : text == 1 ? '等待装车' : text == 2 ? '正在装车' : '装车完成'
}
},
{
title: "排队号",
align: "center",
dataIndex: "sortNo",
sorter: true,
},
{
title: "操作",
key: "action",
align: "center",
fixed: "right",
width: 147,
scopedSlots: { customRender: "action" }
}
],
data: [],
tableLoading: false,//防止快速点击时,没获取到新数据
pagination: {
current: 1,
pageSize: 10, // 默认每页显示数量
total: 0,
showSizeChanger: true, // 显示可改变每页数量
pageSizeOptions: ['10', '20', '30', '50', '100'], // 每页数量选项
showTotal: total => `共 ${total} 条`, // 显示总数
showSizeChange: (current, pageSize) => this.pageSize = pageSize, // 改变每页数量时更新显示
},
};
},
computed: {
...mapState(['bdidInfo']),
},
watch: {
// 监听机构和磅点bdidInfo存储信息的变化
bdidInfo: {
handler(value) {
if (value != null) {
this.queryParam.deptId = value.deptId
this.queryParam.stationId = value.stationId
this.searchQuery()
}
},
immediate: true,
}
},
methods: {
// 搜索列表数据
searchQuery() {
const that = this
this.tableLoading = true
let param = { ...this.queryParam }
param.pageNo = this.pagination.current
param.pageSize = this.pagination.pageSize
getAction(this.url.list, param).then(res => {
if (res.success) {
that.data = res.result.records
// this.data.forEach((res, index) => {//测试=>这里是重复时,让排队号变成1,2,3,4,...
// res.sortNo = index + 1
// })
that.pagination.total = res.result.total
} else {
this.$message.error(res.message || res.msg)
}
setTimeout(() => {
that.tableLoading = false
}, 200)
})
},
// 重置
searchReset() {
this.pagination.current = 1
this.pagination.pageSize = 10
this.queryParam.carNumber = ''
this.queryParam.bankPositon = ''
this.queryParam.varietyName = ''
this.searchQuery()
},
// table的change事件
tableChange(e) {
const { current, pageSize } = e;
this.pagination.current = current;
this.pagination.pageSize = pageSize;
this.searchQuery();
},
// 拖动排序
customRow(record, index) {
const that = this
return {
// FIXME: draggable: true 不生效还不晓得是什么原因,先使用鼠标移入事件设置目标行的draggable属性
props: {
// draggable: 'true'
},
style: {
cursor: "move"
},
on: {
// 鼠标移入
mouseenter: event => {
// 兼容IE
var ev = event || window.event;
ev.target.draggable = true;
},
// 开始拖拽
dragstart: event => {
var ev = event || window.event; // 兼容IE
ev.stopPropagation();// 阻止冒泡
// 得到源目标数据
that.dragStartIndex = index;
that.sourceObj = record;
},
// 拖动元素经过的元素
dragover: event => {
var ev = event || window.event;
ev.preventDefault();// 阻止默认行为
},
// 鼠标松开
drop: event => {
var ev = event || window.event;
ev.stopPropagation(); // 阻止冒泡
// 得到目标数据
that.targetObj = record;
// let _data = JSON.parse(JSON.stringify(that.data));
// _data[that.dragStartIndex] = that.data[index];
// _data[index] = that.data[that.dragStartIndex];
// that.data = _data;
// console.log(that.data)
// console.log(that.sourceObj, '源数据')
that.getDragData(that.sourceObj, that.targetObj)
}
}
};
},
// 获取拖拽的数据=>拖拽的接口
getDragData(sourceObj, targetObj) {
const that = this
// console.log(sourceObj, targetObj)
if (that.data && that.data.length > 0) {//防止快速点击时,获取到的数据不是最新的
that.data.forEach(item => {
if (item.id == sourceObj.id && item.sortNo != sourceObj.sortNo) {
// that.sourceObj = item;
// console.log(item.sortNo, sourceObj.sortNo, '排队号不一致')
that.searchQuery()
return
}
})
}
if (sourceObj.id == targetObj.id || sourceObj.sortNo == targetObj.sortNo) {//防止快速点击时,获取到的数据不是最新的
this.searchQuery()
return
}
let param = {
"queueInfo": [
{
id: sourceObj.id,
sortNo: targetObj.sortNo,
}, {
id: targetObj.id,
sortNo: sourceObj.sortNo,
}
]
}
// console.log(sourceObj.sortNo + '-' + targetObj.sortNo, that.dragStartIndex)
putAction(this.url.queueInfoSort, param).then(res => {
if (res.success) {
that.tableLoading = true //开启动画=>防止快速点击时,获取到的数据不是最新的
that.searchQuery()
that.$message.success(res.message || res.msg)
} else {
this.$message.error(res.message || res.msg)
}
})
},
}
};
</script>
<style scoped>
.resize-table-th {
position: relative;
}
.table-draggable-handle {
/* width: 10px !important; */
height: 100% !important;
left: auto !important;
right: -5px;
cursor: col-resize;
touch-action: none;
border: none;
}
</style>
3.出现的问题:
1.拖拽过程中,出现排队号重复的问题(后台不重复)=>原因:获取列表数据的方法还没完成,连续两次运行拖拽的接口
2.拖拽过程中,出现排队号数据过时的问题=>没有获取到最新的数据
4.初始拖拽版本:
<template>
<a-table bordered :columns="columns" :components="components" :data-source="data" :customRow="customRow">
<template v-slot:action>
<a href="javascript:;"></a>
</template>
</a-table>
</template>
<script>
import Vue from "vue";
import VueDraggableResizable from "vue-draggable-resizable";
// 可拖拽表格
// "vue-draggable-resizable": "2.1.0"
// "ant-design-vue": "^1.5.5"
Vue.component("vue-draggable-resizable", VueDraggableResizable);
var that;
export default {
name: "App",
data() {
this.components = {
header: {
cell: (h, props, children) => {
const { key, ...restProps } = props;
// console.log("ResizeableTitle", key);
const col = this.columns.find(col => {
const k = col.dataIndex || col.key;
return k === key;
});
if (!col || !col.width) {
return h("th", { ...restProps }, [...children]);
}
const dragProps = {
key: col.dataIndex || col.key,
class: "table-draggable-handle",
attrs: {
w: 10,
x: col.width,
z: 1,
axis: "x",
draggable: true,
resizable: false
},
on: {
dragging: (x, y) => {
console.log(x, y);
col.width = Math.max(x, 1);
}
}
};
const drag = h("vue-draggable-resizable", { ...dragProps });
return h("th", { ...restProps, class: "resize-table-th" }, [
...children,
drag
]);
}
}
};
return {
data: [
{
key: 0,
date: "2018-02-11",
amount: 120,
type: "income",
note: "transfer"
},
{
key: 1,
date: "2018-03-11",
amount: 243,
type: "income",
note: "transfer"
},
{
key: 2,
date: "2018-04-11",
amount: 98,
type: "income",
note: "transfer"
}
],
columns: [
{
title: "Date",
dataIndex: "date",
width: 200
},
{
title: "Amount",
dataIndex: "amount",
width: 100
},
{
title: "Type",
dataIndex: "type",
width: 100
},
{
title: "Note",
dataIndex: "note",
width: 100
},
{
title: "Action",
key: "action",
scopedSlots: { customRender: "action" }
}
],
sourceObj: "",
targetObj: '',
// 拖动排序
customRow(record, index) {
return {
// FIXME: draggable: true 不生效还不晓得是什么原因,先使用鼠标移入事件设置目标行的draggable属性
props: {
// draggable: 'true'
},
style: {
cursor: "pointer"
},
on: {
// 鼠标移入
mouseenter: event => {
// 兼容IE
var ev = event || window.event;
ev.target.draggable = true;
},
// 开始拖拽
dragstart: event => {
// 兼容IE
var ev = event || window.event;
// 阻止冒泡
ev.stopPropagation();
// 得到源目标数据
// console.log(that);
that.dragStartIndex = index;
that.sourceObj = record;
},
// 拖动元素经过的元素
dragover: event => {
// 兼容 IE
var ev = event || window.event;
// 阻止默认行为
ev.preventDefault();
},
// 鼠标松开
drop: event => {
// 兼容IE
var ev = event || window.event;
// 阻止冒泡
ev.stopPropagation();
// 得到目标数据
that.targetObj = record;
// 注意=>这里会调换数据,记得注释
let _data = JSON.parse(JSON.stringify(that.data));
_data[that.dragStartIndex] = that.data[index];
_data[index] = that.data[that.dragStartIndex];
that.data = _data;
console.log(that.data, '拖拽后的数据')
console.log(that.sourceObj, '源数据')
console.log(that.targetObj, '目标数据')
}
}
};
}
};
},
mounted() {
that = this;
},
methods: {
}
};
</script>
<style>
.resize-table-th {
position: relative;
}
.table-draggable-handle {
/* width: 10px !important; */
height: 100% !important;
left: auto !important;
right: -5px;
cursor: col-resize;
touch-action: none;
border: none;
}
</style>
5.相关知识:
文章来源地址https://www.toymoban.com/news/detail-659243.html
到了这里,关于【ant-design-vue】实现table的拖拽排序(拖拽行和伸缩列):的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!