import _ from 'lodash' const events = { start: 'mousedown', move: 'mousemove', stop: 'mouseup' } var columnsAll = [] var columnsKey = '' const DragHandler = { name: 'nio-drag-handler', //获取混入的方法(重新设置表头宽度) inject: ['onResizeColumn'], props: { column: { type: Object, required: true }, minWidth: { type: Number, required: true } }, data() { return { dragging: false, thWidth: 0,// 列头的宽度,用于计算 startX: 0, moveEvent: { remove: function() { } }, stopEvent: { remove: function() { } } } }, //销毁监听 beforeDestroy() { this.removeEvents() }, methods: { //鼠标开始拖拽 handleMouseDown(e) { e.stopPropagation() e.preventDefault() this.handleStart(e) }, handleStart(e) { console.log(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]) } } const ResizeHeaderOne = function(val, name) { columnsAll = val columnsKey = name return (h, props, children) => { const { key, column, ...restProps } = props let col = {} // 处理多级表头 col = getRenderCoL(key, val) let content = [].concat(children) if (col) { const handlerVNode = h(DragHandler, { props: { width: col.width, minWidth: Math.min(col.width, 100), column: col } }, []) content = content.concat( handlerVNode ) } return h('th', { key, props: { col }, ...Object.assign({}, restProps, { class: (restProps.class || '') + ' nio-header-th' }) }, content) } } export const ResizeHeader = { methods: { drag(columns, name) { return { header: { cell: ResizeHeaderOne(columns, name) } } } } } const getRenderCoL = (key, tbCols) => { let result = '' _.forEach(tbCols, (item) => { if (item.children) { result = getRenderCoL(key, item.children) return !result } else { const k = item.dataIndex || item.key if (k === key) { result = item return false } } }) return result } //拖拽的节流方法 const throttle2 = (fn, delay) => { let valid = true return (...args) => { if (!valid) { return } valid = false setTimeout(() => { fn(...args) valid = true }, delay) } } //对table组件进行重构的核心方法组件 //监听鼠标移动的方法 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 { moving: false, //这个属性是为了在拖拽时 阻止表头触发排序的功能 onResizeColumn } }, methods: { _resizeColumn(w, column) { this.moving = true let time = setTimeout(() => { this.moving = false clearTimeout(time) }, 2000) //在拖拽时找到对应表头 重新设置表头的宽度 let num = -1 let numOne = -1 for (let i = 0; i < columnsAll.length; i++) { if (columnsAll[i].dataIndex === column.dataIndex) { num = i break } if (columnsAll[i].children && columnsAll[i].children.length > 0) { for (let j = 0; j < columnsAll[i].children.length; j++) { if (columnsAll[i].children[j].dataIndex === column.dataIndex) { num = i numOne = j break } } } } // const matchedIndex = columns.findIndex(item => item.dataIndex === column.dataIndex) // console.log(matchedIndex) // columns[matchedIndex].width = w if (numOne > -1) { columnsAll[num].children[numOne].width = w } else { columnsAll[num].width = w } this[columnsKey] = columnsAll } } }