diff --git a/src/components/table/mixin.js b/src/components/table/mixin.js index 3422455f..ef84684e 100644 --- a/src/components/table/mixin.js +++ b/src/components/table/mixin.js @@ -6,6 +6,7 @@ export default { cellClassName = row.cellClassName[column.key]; } return [ + `${this.prefixCls}-column-${column.__id}`, { [`${cellClassName}`]: cellClassName, // cell className [`${column.className}`]: column.className, // column className diff --git a/src/components/table/table-head.vue b/src/components/table/table-head.vue index 7c791ae2..7b227496 100644 --- a/src/components/table/table-head.vue +++ b/src/components/table/table-head.vue @@ -60,6 +60,13 @@ +
@@ -94,6 +101,13 @@ columnRows: Array, fixedColumnRows: Array }, + data () { + return { + draggingColumn: null, + dragging: false, + dragState: {} + }; + }, computed: { styles () { const style = Object.assign({}, this.styleObject); @@ -222,6 +236,100 @@ } else { return this.headRows[rowIndex][index]; } + }, + handleMouseDown (column, event) { + if (this.$isServer) return; + + if (this.draggingColumn) { + this.dragging = true; + + const table = this.$parent; + const tableEl = table.$el; + const tableLeft = tableEl.getBoundingClientRect().left; + const columnEl = this.$el.querySelector(`th.ivu-table-column-${column.__id}`); + const columnRect = columnEl.getBoundingClientRect(); + const minLeft = columnRect.left - tableLeft + 30; + + table.showResizeLine = true; + + this.dragState = { + startMouseLeft: event.clientX, + startLeft: columnRect.right - tableLeft, + startColumnLeft: columnRect.left - tableLeft, + tableLeft + }; + + const resizeProxy = table.$refs.resizeLine; + resizeProxy.style.left = this.dragState.startLeft + 'px'; + + document.onselectstart = function() { return false; }; + document.ondragstart = function() { return false; }; + + const handleMouseMove = (event) => { + const deltaLeft = event.clientX - this.dragState.startMouseLeft; + const proxyLeft = this.dragState.startLeft + deltaLeft; + + resizeProxy.style.left = Math.max(minLeft, proxyLeft) + 'px'; + }; + + const handleMouseUp = () => { + if (this.dragging) { + const { + startColumnLeft, + startLeft + } = this.dragState; + + const finalLeft = parseInt(resizeProxy.style.left, 10); + const columnWidth = finalLeft - startColumnLeft; + + const _column = table.columns.find(item => item.__id === column.__id); + if (_column) _column.width = columnWidth; + table.$emit('on-column-width-resize', column.width, startLeft - startColumnLeft, column, event); + + document.body.style.cursor = ''; + this.dragging = false; + this.draggingColumn = null; + this.dragState = {}; + + table.showResizeLine = false; + } + + document.removeEventListener('mousemove', handleMouseMove); + document.removeEventListener('mouseup', handleMouseUp); + document.onselectstart = null; + document.ondragstart = null; + }; + + document.addEventListener('mousemove', handleMouseMove); + document.addEventListener('mouseup', handleMouseUp); + } + }, + handleMouseMove (column, event) { + let target = event.target; + + while (target && target.tagName !== 'TH') { + target = target.parentNode; + } + + if (!column || !column.resizable) return; + + if (!this.dragging) { + let rect = target.getBoundingClientRect(); + + const bodyStyle = document.body.style; + + if (rect.width > 12 && rect.right - event.pageX < 8) { + bodyStyle.cursor = 'col-resize'; + this.draggingColumn = column; + } else if (!this.dragging) { + bodyStyle.cursor = ''; + this.draggingColumn = null; + } + } + }, + handleMouseOut () { + if (this.$isServer) return; + document.body.style.cursor = ''; } } }; diff --git a/src/components/table/table.vue b/src/components/table/table.vue index 4267fcd8..5cd7c8d9 100644 --- a/src/components/table/table.vue +++ b/src/components/table/table.vue @@ -94,6 +94,7 @@
+
@@ -235,6 +236,7 @@ showHorizontalScrollBar:false, headerWidth:0, headerHeight:0, + showResizeLine: false }; }, computed: { diff --git a/src/styles/components/table.less b/src/styles/components/table.less index e202b7cf..8e93c644 100644 --- a/src/styles/components/table.less +++ b/src/styles/components/table.less @@ -25,6 +25,15 @@ box-sizing: border-box; //position: relative; + &-resize-line{ + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: 1px; + border-right: 1px dashed @border-color-split; + } + &-hide{ opacity: 0; } @@ -75,6 +84,22 @@ &-header{ overflow: hidden; + thead{ + tr{ + th{ + position: relative; + } + } + } + &-resizable{ + position: absolute; + width: 10px; + height: 100%; + bottom: 0; + right: -5px; + cursor: col-resize; + z-index: 1; + } } &-body{ //overflow: auto;