vue实现表格拖动列宽
实现表格列宽拖动的核心思路
通过监听鼠标事件(mousedown、mousemove、mouseup)实现拖动逻辑。在表头列分隔线处添加可拖拽区域,拖动时动态修改列的宽度。

基础HTML结构示例
<template>
<table>
<thead>
<tr>
<th v-for="(col, index) in columns" :key="index" :style="{ width: col.width + 'px' }">
{{ col.title }}
<div class="resize-handle" @mousedown="startResize(index, $event)"></div>
</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, rowIndex) in data" :key="rowIndex">
<td v-for="(col, colIndex) in columns" :key="colIndex" :style="{ width: col.width + 'px' }">
{{ row[col.key] }}
</td>
</tr>
</tbody>
</table>
</template>
CSS样式关键部分
.resize-handle {
width: 5px;
height: 100%;
background: transparent;
position: absolute;
right: 0;
top: 0;
cursor: col-resize;
}
th {
position: relative;
user-select: none;
}
Vue组件实现逻辑
export default {
data() {
return {
columns: [
{ title: '姓名', key: 'name', width: 150 },
{ title: '年龄', key: 'age', width: 100 },
{ title: '地址', key: 'address', width: 300 }
],
data: [...],
activeIndex: null,
startX: 0,
startWidth: 0
}
},
methods: {
startResize(index, e) {
this.activeIndex = index
this.startX = e.clientX
this.startWidth = this.columns[index].width
document.addEventListener('mousemove', this.handleResize)
document.addEventListener('mouseup', this.stopResize)
},
handleResize(e) {
if (this.activeIndex === null) return
const deltaX = e.clientX - this.startX
this.columns[this.activeIndex].width = Math.max(30, this.startWidth + deltaX)
},
stopResize() {
this.activeIndex = null
document.removeEventListener('mousemove', this.handleResize)
document.removeEventListener('mouseup', this.stopResize)
}
}
}
性能优化建议
拖动过程中使用requestAnimationFrame优化渲染性能:

handleResize(e) {
if (this.activeIndex === null) return
window.requestAnimationFrame(() => {
const deltaX = e.clientX - this.startX
this.columns[this.activeIndex].width = Math.max(30, this.startWidth + deltaX)
})
}
边界情况处理
添加最小宽度限制防止列过窄:
this.columns[this.activeIndex].width = Math.max(30, this.startWidth + deltaX)
完整组件示例
可复用的表格组件应接收columns和data作为props:
props: {
columns: {
type: Array,
required: true
},
data: {
type: Array,
required: true
}
}
注意事项
- 确保表头单元格设置position: relative
- 拖拽手柄需要绝对定位在列右侧
- 移除事件监听防止内存泄漏
- 考虑添加防抖处理高频resize事件
- 移动端需要额外处理touch事件






