**
近期想换一套ui框架,就选择了an design vue,但是发现table组件本身没有像element ui一样集成了列可以伸缩,看到官网提供了一个插件vue-draggable-resizable,我按照官网的例子copy了一下,遇到各种问题
1、我的colums数据没有写width
2、我有的列如操作列没有设置dataIndex 、key
3、我表格使用了复选框后一直报错Cannot read property ‘width’ of undefined
**
:w 默认宽度
:h 默认高度
:x=“50” 默认水平坐标 注意相对元素是谁
:y=“50” 默认垂直最表 注意相对元素是谁
:min-width=“50” 最小宽度
:min-height=“50” 最小高度
:parent=“true” 限制不能拖出父元素
parent=".p-event" 限制不能拖出class为p-event的元素
:grid 水平和垂直移动 每次分别能够走多少像素
class-name 自定义组件class
@dragging=“onDrag” 每当拖动组件时调用。
@resizing=“onResize” 每当组件调整大小时调用。
@dragstop=“onDragstop” 每当组件停止拖动时调用。
@resizestop=“onResizstop” 每当组件停止调整大小时调用
@deactivated=“onDeactivated” 每当用户单击组件外的任何位置时调用
@activated=“onActivated” 单击组件时调用,以显示句柄。备注:句柄就是点击组件后上下左右的可以拉伸的方块点
//mixins/tableDragResize.js
import Vue from 'vue'
import VueDraggableResizable from 'vue-draggable-resizable'
Vue.component('vue-draggable-resizable', VueDraggableResizable)
/**
* @param { 表格columns } tbCols
*/
function initDrag(tbCols) {
const draggingMap = {}
tbCols.forEach((col) => {
const key = col.dataIndex || col.key//这儿要求表格数据中要有这两个属性
draggingMap[key] = col.width || 0
})
const draggingState = Vue.observable(draggingMap)
return (h, props, children) => {
let thDom = null
const { key, ...restProps } = props
let col
if (key === 'selection-column') {
//表格加了复选框,不加这个判断col会是undefided
col = {}
} else {
col = tbCols.find((item) => {
const k = item.dataIndex || item.key
return k === key
})
}
if (!col.width) {//这儿要求表格数据中要有宽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={draggingState[key]}
class="resize-table-th"
>
{children}
<vue-draggable-resizable
key={col.dataIndex || col.key}
class="table-draggable-handle"
w={10}
x={col.width || draggingState[key]}
z={1}
axis="x"
draggable={true}
resizable={false}
onDragging={onDrag}
onDragstop={onDragstop}
></vue-draggable-resizable>
</th>
)
}
}
export default {
methods: {
/**
* https://github.com/mauricius/vue-draggable-resizable
* 表格列可拖拽
* 表格上使用::components="drag(columns)"
* tips:columns中需包含dataIndex或者key和width(Number)
*/
drag(columns) {
return {
header: {
cell: initDrag(columns),
},
}
},
},
}
使用的代码如下:
//user.vue
<template>
<a-table
bordered
:components="drag(tableColumns)"
:columns="tableColumns"
:data-source="userList"
:row-selection="rowSelection"
rowKey="userId"
>
</a-table>
</template>
<script>
import tableDragResize from '@/mixins/tableDragResize'
export default {
name: 'User',
mixins: [tableDragResize],
data(){
return{
tableColumns: [
{
title: '用户编号',
dataIndex: 'userId',
ellipsis: true,
width: 100,
},
{
title: '用户名称',
dataIndex: 'userName',
ellipsis: true,
width: 100,
},
{
title: '操作',
key: 'operation',
width: 130,
scopedSlots: { customRender: 'operation' },
},
]
}}
}
</script>
还有在全局哪里加上拖拽的样式
.resize-table-th {
position: relative;
.table-draggable-handle {
height: 100% !important;
bottom: 0;
left: auto !important;
right: -5px;
cursor: col-resize;
touch-action: none;
}
}
4、注意事项:
1)若是表格有复选框的话:官网中 没有封装带复选框的情况那么这段代码会报错
Cannot read property ‘width’ of undefined
const { key, ...restProps } = props;
const col = this.columns.find((item) => {
const k = item.dataIndex || item.key;
return k === key;
});
原因是我们加了复选框后,在遍历的时候就会有一个key为‘selection-column’的列,导致了col为undefined,所以在下面的col.width的逻辑中就报错了。如果要解决此问题,只需要将这个列单独处理即可,如下:
const { key, ...restProps } = props
let col
if (key === 'selection-column') {
//表格加了复选框
col = {}
} else {
col = tbCols.find((item) => {
const k = item.dataIndex || item.key
return k === key
})
}
2)还有就是表格要加bordered属性,以及colums数据中一定要加width宽度,不然会报错
3)最重要的是表格的colums数据中要加dataIndex 或者key属性,否则报错。
以上都是自己遇到的坑,血淋淋的。。。