table组件—可伸缩列

目录

一、概述

二、详解

三、拓展


一、概述

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>

猜你喜欢

转载自blog.csdn.net/weixin_42472040/article/details/110943098
今日推荐