const tableMixin = {
data() {
return {
dragState: {}, // 记录子表的列宽移动的一些数值
dragging: false // 子表是否在重置列宽
}
},
methods: {
handleMouseMove(event) {
let target = event.target
while (target && target.tagName !== 'TH') {
target = target.parentNode
}
if (!this.dragging) {
const rect = target.getBoundingClientRect()
const bodyStyle = document.body.style
if (rect.width > 12 && rect.right - event.pageX < 8) {
// 拖拽的鼠标样式
bodyStyle.cursor = 'col-resize'
} else if (!this.dragging) {
bodyStyle.cursor = ''
}
}
},
handleMouseOut() {
document.body.style.cursor = ''
},
handleMouseDown(event) {
// 开始拖拽
this.dragging = true
// 当前拖拽的列所在的表格
let tableEl = event.target
// 当前所在列(单元格)
let thEL = event.target
while (tableEl && tableEl.tagName !== 'TABLE') {
tableEl = tableEl.parentNode
}
// 获取列宽拖拽的显示线(拖拽线)
const resizeProxy = tableEl.querySelector('.table-column-line')
while (thEL && thEL.tagName !== 'TH') {
thEL = thEL.parentNode
}
const columnRect = thEL.getBoundingClientRect()
thEL.classList.add('noclick')
this.dragState = {
startMouseLeft: event.clientX, // 鼠标开始的地方
columnWidth: columnRect.width // th开始拖拽的宽度
}
resizeProxy.style.top = tableEl.getBoundingClientRect().top + 'px'
// resizeProxy.style.height = tableEl.getBoundingClientRect().height + 'px'
resizeProxy.style.left = this.dragState.startMouseLeft + 'px'
resizeProxy.classList.remove('dn')
document.onselectstart = function() {
return false
}
document.ondragstart = function() {
return false
}
const handleMouseMove = event => {
// 拖拽中,拖拽线与鼠标的位置同步
resizeProxy.style.left = event.clientX + 'px'
}
const handleMouseUp = () => {
if (this.dragging) {
// 拖拽完毕
const { startMouseLeft, columnWidth } = this.dragState
const finalLeft = parseInt(resizeProxy.style.left, 10)
const columnWidthDiff = finalLeft - startMouseLeft
const finalColumnWidth = columnWidthDiff + columnWidth
const columnMinWidth = parseInt(thEL.style.minWidth, 10)
thEL.style.width = finalColumnWidth + 'px'
// 当单元格宽度改变时 表格宽度也进行改变: 1)有最小宽度时宽度改变了 2)无最小宽度时
if (
(columnMinWidth && finalColumnWidth >= columnMinWidth) ||
!columnMinWidth
) {
tableEl.style.width =
columnWidthDiff + tableEl.clientWidth + 'px'
}
document.body.style.cursor = ''
this.dragging = false
this.dragState = {}
resizeProxy.classList.add('dn')
}
document.removeEventListener('mousemove', handleMouseMove)
document.removeEventListener('mouseup', handleMouseUp)
document.onselectstart = null
document.ondragstart = null
setTimeout(function() {
thEL.classList.remove('noclick')
}, 0)
}
document.addEventListener('mousemove', handleMouseMove)
document.addEventListener('mouseup', handleMouseUp)
}
}
}
export default tableMixin
【表格使用】
// 引入刚刚写的mixin
import tableMixin from './tableMixin'
// 引入混合
mixins: [tableMixin]
// 在th表头写入
class="table-column-line"
@mousemove="handleMouseMove"
@mouseout="handleMouseOut"
@mousedown="handleMouseDown"