文章目录
一、项目初始化
1.1 技术栈说明
- Vue 3 Composition API
vuedraggable:用于实现拖拽排序- 原生 DOM 操作:用于列宽调整
- Element Plus(可选):用于样式和表格基础结构
1.2 项目结构图(Mermaid)
二、构建基础表格组件
2.1 创建基本表格结构
<!-- TableComponent.vue -->
<template>
<div class="table-container">
<table>
<thead>
<tr>
<th v-for="(col, index) in columns" :key="col.key">
{{ col.label }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, rowIndex) in tableData" :key="row.id">
<td v-for="col in columns" :key="col.key">{{ row[col.key] }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script setup>
import { ref } from 'vue'
const columns = ref([
{ label: '姓名', key: 'name' },
{ label: '年龄', key: 'age' },
{ label: '地址', key: 'address' }
])
const tableData = ref([
{ id: 1, name: '小明', age: 25, address: '北京' },
{ id: 2, name: '小红', age: 30, address: '上海' },
{ id: 3, name: '小刚', age: 28, address: '广州' }
])
</script>
三、实现行拖拽排序
3.1 安装依赖
npm install vuedraggable
3.2 使用 vuedraggable 实现拖拽
<template>
<draggable v-model="tableData" tag="tbody" item-key="id">
<tr v-for="row in tableData" :key="row.id">
<td v-for="col in columns" :key="col.key">{{ row[col.key] }}</td>
</tr>
</draggable>
</template>
<script setup>
import draggable from 'vuedraggable'
</script>
四、实现列宽拖拽调整
4.1 基本样式设置
th {
position: relative;
padding-right: 8px;
}
.resizer {
position: absolute;
top: 0;
right: 0;
width: 5px;
cursor: col-resize;
user-select: none;
}
4.2 添加拖拽逻辑
<th
v-for="(col, index) in columns"
:key="col.key"
:style="{ width: col.width + 'px' }"
@mousedown="startResize($event, index)"
>
{{ col.label }}
<span class="resizer"></span>
</th>
let startX, startWidth
const startResize = (e, index) => {
startX = e.clientX
startWidth = columns.value[index].width || 100
document.addEventListener('mousemove', resize)
document.addEventListener('mouseup', stopResize)
function resize(e) {
const newWidth = startWidth + (e.clientX - startX)
columns.value[index].width = Math.max(newWidth, 60)
}
function stopResize() {
document.removeEventListener('mousemove', resize)
document.removeEventListener('mouseup', stopResize)
}
}
五、实现列拖拽排序
5.1 转换列为可拖拽结构
<draggable v-model="columns" tag="tr" item-key="key" direction="horizontal">
<th
v-for="(col, index) in columns"
:key="col.key"
:style="{ width: col.width + 'px' }"
@mousedown="startResize($event, index)"
>
{{ col.label }}
<span class="resizer"></span>
</th>
</draggable>
5.2 保证数据对应正确列
<tr v-for="row in tableData" :key="row.id">
<td v-for="col in columns" :key="col.key">
{{ row[col.key] }}
</td>
</tr>
六、可拓展功能实现
6.1 固定列实现(示意)
<th :class="{ 'sticky-left': index === 0 }"> ... </th>
.sticky-left {
position: sticky;
left: 0;
background-color: #fff;
z-index: 2;
}
6.2 列顺序保存到本地存储
watch(columns, (val) => {
localStorage.setItem('columns', JSON.stringify(val))
}, { deep: true })
onMounted(() => {
const saved = localStorage.getItem('columns')
if (saved) {
columns.value = JSON.parse(saved)
}
})
七、总结
通过本文,我们使用 Vue 3 实现了一个具备以下功能的可配置表格组件:
- ✅ 行拖拽排序
- ✅ 列宽度调整
- ✅ 列顺序拖拽
- ✅ 固定列支持
- ✅ 用户列设置持久化
该组件可广泛应用于数据管理后台、内容管理系统等场景,未来可继续拓展如列隐藏、分组列头、自定义渲染等功能。
到这里,这篇文章就和大家说再见啦!我的主页里还藏着很多 篇 前端 实战干货,感兴趣的话可以点击头像看看,说不定能找到你需要的解决方案~
创作这篇内容花了很多的功夫。如果它帮你解决了问题,或者带来了启发,欢迎:
点个赞❤️ 让更多人看到优质内容
关注「前端极客探险家」🚀 每周解锁新技巧
收藏文章⭐️ 方便随时查阅
📢 特别提醒:
转载请注明原文链接,商业合作请私信联系
感谢你的阅读!我们下篇文章再见~ 💕


被折叠的 条评论
为什么被折叠?



