Vue+ant-design-vue 表格实现可拖动的伸缩列
应客户要求,表格要实现左右拖动列边框实现列宽的扩大和缩小;ant-design-vue官方文档中,table组件中提供了此功能的示例代码。尝试过程中处处报错。经过多次百度与尝试最后整理出一套可用的代码。这篇笔记以 步骤 的形式一步一步的记录如何实现这个功能。
步骤一:安装集成的 vue-draggable-resizable 插件
npm install --save vue-draggable-resizable
步骤二:在项目的main.js中引入插件
// 挂载全局使用的方法
import VueDraggableResizable from 'vue-draggable-resizable'
Vue.component('vue-draggable-resizable', VueDraggableResizable)
步骤三:在使用页面中重新引入根vue实例和插件
import Vue from 'vue'
import VueDraggableResizable from 'vue-draggable-resizable'
步骤四:ant-design-vue 的 table 组件中添加components属性
<a-table
size="small"
bordered
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:scroll="{x:'max-content'}"
:rowKey="(record,index)=>{return index+1}"
:components="components"
>
</a-table>
步骤五:定义components属性代码(表头columns中,每一列都要设置width,如果不设置width属性,拖动时不生效)
data() {
this.components = {
header: {
cell: (h, props, children) => {
const { key, ...restProps } = props
// 此处的this.columns 是定义的table的表头属性变量
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) => {
col.width = Math.max(x, 1)
},
},
}
const drag = h('vue-draggable-resizable', { ...dragProps })
return h('th', { ...restProps, class: 'resize-table-th' }, [...children, drag])
},
},
}
return {
dataSource:[],
defColumns:[{
title: '序号',
dataIndex: 'rowIndex',
key: 'rowIndex',
width: 80,
align: 'center',
customRender: function (text, r, index) {
return parseInt(index) + 1
},
className: 'columnsColor',
},{
title: '价格状态',
dataIndex: 'customerName1',
className: 'columnsColor',
scopedSlots: { customRender: 'customerName1' },
width: 200,
}]
},
步骤六:样式(style一定要记得添加.table-draggable-handle 和 .resize-table-th 两个class。并且style标签不能家scoped属性)
<style>
.table-draggable-handle {
/* width: 10px !important; */
height: 100% !important;
left: auto !important;
right: -5px;
cursor: col-resize;
touch-action: none;
border: none;
position: absolute;
transform: none !important;
bottom: 0;
}
.resize-table-th {
position: relative;
}
</style>
完整代码
<template>
<a-table
size="small"
bordered
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:scroll="{x:'max-content'}"
:rowKey="(record,index)=>{return index+1}"
:components="components"
>
</a-table>
</template>
<script>
import Vue from 'vue'
import VueDraggableResizable from 'vue-draggable-resizable'
export default {
components: {
VueDraggableResizable
},
data() {
this.components = {
header: {
cell: (h, props, children) => {
const { key, ...restProps } = props
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) => {
col.width = Math.max(x, 1)
},
},
}
const drag = h('vue-draggable-resizable', { ...dragProps })
return h('th', { ...restProps, class: 'resize-table-th' }, [...children, drag])
},
},
}
return {
dataSource:[],
defColumns:[{
title: '序号',
dataIndex: 'rowIndex',
key: 'rowIndex',
width: 80,
align: 'center',
customRender: function (text, r, index) {
return parseInt(index) + 1
},
className: 'columnsColor',
},{
title: '价格状态',
dataIndex: 'customerName1',
className: 'columnsColor',
scopedSlots: { customRender: 'customerName1' },
width: 200,
}]
}
},
created() {},
}
</script>
<style>
.table-draggable-handle {
/* width: 10px !important; */
height: 100% !important;
left: auto !important;
right: -5px;
cursor: col-resize;
touch-action: none;
border: none;
position: absolute;
transform: none !important;
bottom: 0;
}
.resize-table-th {
position: relative;
}
</style>