vue表格实现拖拽改变列宽入坑记(包含多层表头的处理和动态表头的处理)

497 阅读1分钟

第一步:安装插件,加载进mixins(混入),加载样式到全局。

yarn add vue-draggable-resizable
import VueDraggableResizable from 'vue-draggable-resizable'

第二步:在表格上使用:components = this.handleDrag(this.columns) 注意点:因为表格可能存在这种包含子集,所以将表头转成一维数组比较好进行查找 image.png

//注册组件,我使用的是局部注册
 components: {VueDraggableResizable},
 methods: {
     handleDrag(column) {
     //将表头数组转换成一维数组,可用于处理复杂表头
      const _column = this.handleArr(column)
      return {
        header: {
          cell: (h, props, children) => {
            const { key, ...restProps } = props
            const col = _column.find((col,index) => {
            //如果没有 dataIndex|key,就用下标查找
            const k = col.dataIndex || col.key || index
              return k === key
            })
            if (!col || !col.width) {
              return h('th', { ...restProps }, [
                ...children
              ])
            }
            const dragProps = {
              key: (col.dataIndex || col.key) =='title' ? 'title1' :  (col.dataIndex || col.key) ,
              class: 'table-draggable-handle',
              attrs: {
                w: 10,
                x: col.width || 100,
                z: 1,
                axis: 'x',
                draggable: true,
                resizable: false
              },
              on: {
                dragging: (x, y) => {
                  col.width = Math.max(x, 1) || 100
                }
              }
            }
            const drag = h(VueDraggableResizable, {
              ...dragProps
            }) 
            //全局引入使用 'vue-draggable-resizable'替换 VueDraggableResizable
            return h(
              'th',
              { ...restProps, class: 'resize-table-th' },
              [...children, drag]
            )
          }
        }
      }
    },
    //该方法是将多维数组转化成一维数组
    handleArr(arr) {
      let result = []
      arr.forEach(item => {
        if(item.children&& item.children.length) {
          result = result.concat(this.handleArr(item.children))
        } else {
          result.push(item)
        }
      })
      return result
    }
 }

注意点:

  1. 传递的表头形式:必须设置width的值,有dataIndex|key最好要设置

columns: [
        { title: '计划名称',dataIndex: 'title',key: 'title',width: 250,ellipsis: true },
        { title: '所属项目',dataIndex: 'projectName',key: 'projectName',width: 300 },
        { title: '销量',align:'center',
            children: [
              {
                title: '昨日销量',
                dataIndex: 'sellQtyYesterday',
                key: 'sellQtyYesterday',
                align:'center',
                width:100
              },
              {
                title: '7日销量',
                dataIndex: 'sellQty7',
                key: 'sellQty7',
                align:'center',
                width:100
              },
              {
                title: '14日销量',
                dataIndex:'sellQty14',
                key: 'sellQty14',
                align:'center',
                width:100
              },
              {
                title: '30日销量',
                dataIndex: 'sellQty30',
                key: 'sellQty30',
                align:'center',
                width:100
              },
            ]
          }
        ]

2.动态表头的创建:给table绑定key,确保表头改变后,也可以进行拖拽

<a-table :key="showKey">
</a-table>

data(){
    return {
        showKey: 0
    }
},
methods: {
      //在触发表头改变事件的地方更新showKey,或者在获取数据时进行showkey++
     handledimentChange() {
      this.showKey++
     }
}

参考: blog.csdn.net/drunk2/arti…