Ant Design Vue2 表格实现可拖动的伸缩列,阻止拖动后排序

一:安装 vue-draggable-resizable 插件

npm install --save vue-draggable-resizable@2.1.0

 二:如果多处地方需要使用建议放在mixins里面,只有一个页面使用直接写在要使用的页面,我这里是放在mixins里面

import Vue from "vue";

import VueDraggableResizable from "vue-draggable-resizable";

Vue.component("vue-draggable-resizable", VueDraggableResizable);

function initDrag(columns) {

  const draggingMap = {};

  columns.forEach(col => {

    draggingMap[col.key] = col.width;

  });

  const draggingState = Vue.observable(draggingMap);

  return (h, props, children) => {

    let thDom = null;

    // 由于drag事件结束后必然会出发click事件,所以需要一个参数去判断当前操作是click点击事件还是drag拖拽事件

    // 阻止拖动后触发排序事件,此方法只能在vue2+antd1上使用,对于其他版本并不适配。

    let isDrag = false;

    const { key, ...restProps } = props;

    let col;

    if (key === "selection-column") {

      //表格加了复选框,不加这个判断col会是undefided

      col = {};

    } else {

      col = columns.find(col => {

        const k = col.dataIndex || col.key;

        return k === key;

      });

    }

    if (!col || !col.width) {

      return <th {...restProps}>{children}</th>;

    }

    // 拖动时把isdrag参数设置为true

    const onDrag = x => {

      // console.log(x,'开始拖动');

      isDrag = true;

      draggingState[key] = 0;

      col.width = Math.max(x, 1);

    };

    // 拖动结束后把isdrag参数设置为false

    const onDragstop = () => {

      draggingState[key] = thDom.getBoundingClientRect().width;

      // console.log(thDom.getBoundingClientRect().width,'拖动结束');

      isDrag = true;

      // eslint-disable-next-line vue/no-async-in-computed-properties

      setTimeout(() => {

        isDrag = false;

      }, 300);

    };

    // 取出column的click事件,对事件进行判断,如果现在isDrag参数为true,则截胡,防止拖动后触发click事件

    if (restProps.on && restProps.on.click) {

      let clickFunc = restProps.on.click;

      restProps.on.click = event => {

        if (isDrag) {

          return;

        }

        clickFunc(event);

      };

    }

    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>

    );

  };

}

export default {

  methods: {

    drag(columns) {

      return {

        header: {

          cell: initDrag(columns)

        }

      };

    }

  }

};

三:在使用页面中引入mixins js文件

<script >
  import TableDragResizefrom '@/mixins/TableDragResize'

  export default {
    mixins: [TableDragResize], 
    data() {
      return {}
    }
  }
</script>

四:table 组件中添加components属性,drag(columns)方法的参数是当前表头集合数据

<a-table
        ref="table"
        size="middle"
        bordered
        rowKey="id"
        :components="drag(columns)"
        :columns="columns"
        :loading="loading"
        :dataSource="dataSource"
        :pagination="ipagination"
        :rowSelection="{
          selectedRowKeys: selectedRowKeys,
          onChange: onSelectChange
        }"
        @change="handleTableChange"
      >
</a-table>

五:添加以下样式

 /deep/.resize-table-th {
  position: relative;
  .table-draggable-handle {
    height: 100% !important;
    bottom: 0;
    left: auto !important;
    right: -5px;
    cursor: col-resize;
    touch-action: none;
    position: absolute;
  }
}

重点:

1,表头columns中,每列都要设置width,width的值必须Number,如果不设置width属性,拖动时不生效,key和dataIndex同时设置时字段必须保持一致,否则不生效

2,style一定要记得添加.table-draggable-handle 和 .resize-table-th 两个class。如果style样式不生效去掉scoped

3, 表格没有拖动滑块样式问题:.table-draggable-handle 里加上 transform: none !important

4,动态表头无法拖动问题:将columns定义在data中不要放在computed里

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值