目录
一、概述
ant design vue框架中,table组件本身不具备列拖拽功能,若想实现列拖动调整列宽的功能,需要引用vue-draggable-resizable插件。
二、详解
第一步:安装vue-draggable-resizable插件
vue-draggable-resizable插件推荐安装2.1.0版本,最新的2.2.0版本存在问题。
> npm install [email protected]
第二步:创建处理表格列的公共JS文件drag.js
// 位置:@/components/TableDrag/drag.js
import Vue from "vue";
import VueDraggableResizable from "vue-draggable-resizable";
Vue.component("vue-draggable-resizable", VueDraggableResizable);
export default {
methods: {
initDrag(tbCols) {
// 第一步:列宽映射
const draggingMap = {};
tbCols.forEach((col) => {
draggingMap[col.key] = col.width;
});
const draggingState = Vue.observable(draggingMap);
// 第二步:表头渲染
return (h, props, children) => {
// 表头DOM
let thDom = null;
// 获取列的key值和特性
const { key, ...restProps } = props;
// 获取当前列
const col = tbCols.find((col) => {
const k = col.dataIndex || col.key;
return k === key;
});
// 如果当前列没有设置宽度, 直接返回
if (!col.width) {
return <th {...restProps}>{children}</th>;
}
// 开始拖拽监听
const onDrag = (x) => {
draggingState[key] = 0;
col.width = Math.max(x, 1);
};
// 停止拖拽监听
const onDragstop = () => {
draggingState[key] = thDom.getBoundingClientRect().width;
};
return (
<th
{...restProps}
v-ant-ref={(r) => (thDom = r)}
width={col.width}
class="resize-table-th"
>
{children}
<vue-draggable-resizable
key={col.key}
class="table-draggable-handle"
w={10}
x={draggingState[key] || col.width}
z={1}
axis="x"
draggable={true}
resizable={false}
onDragging={onDrag}
onDragstop={onDragstop}
></vue-draggable-resizable>
</th>
);
};
},
}
};
第三步:引入drag.js,并混入当前组件
<script>
// 引入表格拖拽配置
import drag from '@/components/TableDrag/drag';
export default{
mixins: [drag],
};
</script>
第四步:table组件设置components属性
<template>
<!-- 其余属性忽略 -->
<a-table :components="components()" :columns="fileDataCols"></a-table>
</template>
<script>
// 引入表格表头字段
import fileDataCols from '@/pages/fileManage/fileListCols';
export default{
methods: {
components() {
return {
header: {
cell: this.initDrag(fileDataCols),
}
}
}
}
};
</script>
注意,表格的表头必须包含key属性及数值类型的width属性,如下图所示。
第五步:公共样式,及引入
<style scoped lang="less">
// 表格拖拽的样式
// @import "~@/components/TableDrag/style.less";
/deep/ .resize-table-th {
position: relative;
.table-draggable-handle {
transform: none !important;
position: absolute;
height: 100% !important;
bottom: 0;
left: auto !important;
right: -5px;
cursor: col-resize;
touch-action: none;
}
}
</style>
三、拓展
上述步骤仅仅针对静态列的可拖拽配置,若想实现动态列的可拖拽,在上述步骤的基础上,添加如下配置。
<template>
<!-- 其余属性忽略 -->
<a-table :key="timeStamp" :columns="columns"></a-table>
</template>
<script>
// 引入表格表头字段
import fileDataCols from '@/pages/fileManage/fileListCols';
export default{
data() {
return {
timeStamp: +new Date(),
// 必须在data组件选项中声明外部引入的表头字段, 否则拖拽不起作用
fileDataCols,
// 动态列
dyCols: []
};
},
computed: {
columns() {
// 因为拖拽的缘故,表格动态列变化需要重新加载表格组件
this.timeStamp = +new Date();
// 静态列 + 动态列
const ret = [...this.fixedcolumns.start, ...this.dyCols];
return ret;
}
},
methods: {
components() {
return {
header: {
cell: this.initDrag(this.columns),
}
}
}
}
};
</script>