antDesignVue1.7.8的table组件添加列滑动

antDesignVue1.7.8的table组件添加列滑动,亲测该demo是OK的
主要包括两个文件一个demo.vue和header.js

demo.vue文件代码

<a-table ref="baseTable" bordered :components="componentsa" :columns="columns" :dataSource="hxrData" :rowKey="(record, index) => index" :pagination="false"></a-table>
<script>
import { ResizeHeader, customHeaderCell, ResizeColumnProvide } from './header'
export default {
computed: {
    componentsa() {
      // 重新header部分逻辑
      return {
        header: {
          cell: ResizeHeader,
        },
      }
    },
  },
  mixins: [ResizeColumnProvide],
  data(){
	return {
		columns: [],
      hxrColumns: [
        {
          title: 'Age',
          dataIndex: 'age',
          key: 'age',
          resizable: true, // 可拖拽标识
          width: 80 // 注意如果要设可拖拽,要先设宽度
        },
        {
          title: 'Address',
          dataIndex: 'address',
          key: 'address',
        },
        {
          title: 'Tags',
          key: 'tags',
          dataIndex: 'tags',
          scopedSlots: { customRender: 'tags' },
        },
        {
          title: 'Action',
          key: 'action',
          scopedSlots: { customRender: 'action' },
        },
      ],
      hxrData: [
        {
          key: '1',
          name: 'John Brown',
          age: 32,
          address: 'New York No. 1 Lake Park',
          tags: ['nice', 'developer'],
        },
        {
          key: '2',
          name: 'Jim Green',
          age: 42,
          address: 'London No. 1 Lake Park',
          tags: ['loser'],
        },
        {
          key: '3',
          name: 'Joe Black',
          age: 32,
          address: 'Sidney No. 1 Lake Park',
          tags: ['cool', 'teacher'],
        },
      ],
	}
  },
  mounted() {
	//给column绑定   不绑定的话ResizeHeader方法中的参数props无法获取到column信息
	//这里的hxrColumns就是表头的集合
    this.columns = this.hxrColumns.map((item) => Object.assign({}, item, { customHeaderCell }))
  }
}
</script>
<style>
.nio-header-th {
  position: relative;
  isolation: isolate;
}

.nio-drag-handler {
  position: absolute;
  right: 0;
  top: 0;
  height: 100%;
  width: 2px;
  z-index: 1;
  border: 1px dashed #eee;

&:hover,
&:focus {
   cursor: col-resize;
   border: 1px dashed #0bd9d9;
 }
}
</style>

header.js文件代码

function noop() {
}
//重构table组件的核心渲染函数
export const ResizeHeader = (h, props, children) => {
    const { key, column, ...restProps } = props;
    let content = [].concat(children);
    console.log('column', column)
    if (column.resizable) {
        const handlerVNode = h(DragHandler, {
            props: {
                width: column.width,
                minWidth: Math.min(column.width, 100),
                column: column
            }
        }, []);
        content = content.concat(
            handlerVNode
        );
    }

    return h("th", {
        key,
        props: { column },
        ...Object.assign({}, restProps, { class: (restProps.class || "") + " nio-header-th" })
    }, content);
};

const events = {
    start: "mousedown",
    move: "mousemove",
    stop: "mouseup",
};
//对table组件进行重构的核心方法组件
const DragHandler = {
    name: "nio-drag-handler",
    //获取混入的方法(重新设置表头宽度)
    inject: {
        onResizeColumn: {
            default: noop
        }
    },
    props: {
        column: { type: Object, required: true },
        minWidth: { type: Number, required: true }
    },

    data() {
        return {
            dragging: false,
            thWidth: 0,// 列头的宽度,用于计算
            startX: 0,
            moveEvent: {
                remove: noop
            },
            stopEvent: {
                remove: noop
            }
        };
    },
    //销毁监听
    beforeDestroy() {
        this.removeEvents();
    },
    methods: {
        //鼠标开始拖拽
        handleMouseDown(e) {
            e.stopPropagation();
            e.preventDefault();
            this.handleStart(e);
        },

        handleStart(e) {
            this.dragging = true;
            this.removeEvents();
            this.thWidth = this.$el.parentNode.getBoundingClientRect().width;
            if (e instanceof MouseEvent && e.which !== 1) {
                return;
            }
            if (e.stopPropagation) e.stopPropagation();
            this.startX = e.pageX;
            this.moveEvent = addEventListenerWrap(document.documentElement, events.move, this.handleMove);
            this.stopEvent = addEventListenerWrap(document.documentElement, events.stop, this.handleStop);
        },

        handleMove(e) {
            this.updateWidth(e);
        },
        handleStop(e) {
            this.dragging = false;
            this.updateWidth(e);
            this.removeEvents();
        },

        updateWidth(e) {
            let pageX = e.pageX;
            const tmpDeltaX = this.startX - pageX;
            let w = Math.max(this.thWidth - tmpDeltaX, this.minWidth);
            w = Math.min(w, Infinity);
            this.onResizeColumn(w, this.column);
        },

        removeEvents() {
            this.moveEvent.remove();
            this.stopEvent.remove();
        }
    },
    //渲染div 绑定拖拽
    render(h) {
        const line = h("div", { class: "nio-drag-handler-line" }, []);
        return h("div", { class: "nio-drag-handler", on: { mousedown: this.handleMouseDown } }, [line]);
    }
};

//监听鼠标移动的方法
function addEventListenerWrap(target, eventType, cb) {
    if (target && target.addEventListener) {
        target.addEventListener(eventType, cb);
    }

    return {
        remove: () => {
            if (target && target.removeEventListener) {
                target.removeEventListener(eventType, cb);
            }
        },
    };
}


//在table组件中混入的一个方法 provide => onResizeColumn
//目的是在table重写中(DragHandler方法)
//可以用到构造的onResizeColumn方法(重新设置表头的宽度)
export const ResizeColumnProvide = {
    name: "ResizeColumnProvideMixin",
    provide() {
        return {
            onResizeColumn: this.onResizeColumn
        };
    },

    data() {
        const onResizeColumn = throttle2(this._resizeColumn, 30);
        return {
            columnsKey: "columns", //这个属性是table组件表头的集合名称 :columns="columns"
            moving:false, //这个属性是为了在拖拽时 阻止表头触发排序的功能
            onResizeColumn
        };
    },

    methods: {
        _resizeColumn(w, column) {
            const columns = this[this.columnsKey];
            this.moving = true
            let time = setTimeout(() => {
                this.moving = false
                clearTimeout(time)
            }, 2000);
            //在拖拽时找到对应表头 重新设置表头的宽度
            //这就是为什么表头column要绑定customHeaderCell的原因
            const matchedIndex = columns.findIndex(item => item.key === column.key);
            columns[matchedIndex].width = w;
        }
    }
};

//拖拽的节流方法
const throttle2 = (fn, delay) => {
    let valid = true;
    return (...args) => {
        if (!valid) {
            return;
        }
        valid = false;
        setTimeout(() => {
            fn(...args);
            valid = true;
        }, delay);
    };
};

//table组件内置的一个方法
export function customHeaderCell(column) {
    return Object.assign({
        column: column
    });
}


效果图

在这里插入图片描述

  • 26
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值