Vue3 中使用 Sortablejs 实现拖拽排序功能 序号不更新问题
Vue3 中使用 Sortablejs 实现拖拽排序功能 序号不更新问题
- 安装依赖
npm install sortablejs --save
- 简单使用
<template>
<div class="app-container">
<div class="table-header">
<el-button type="primary" @click="handleAdd">添加</el-button>
</div>
<el-table :data="tableData" row-key="code">
<el-table-column width="50">
<template #default>
<el-icon class="drag-handle"><Operation /></el-icon>
</template>
</el-table-column>
<el-table-column label="序号" width="80" align="center">
<template #default="scope">{{ scope.$index + 1 }}</template>
</el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
</el-table>
</div>
</template>
<script setup>
import { ref, onMounted, nextTick } from 'vue'
import Sortable from 'sortablejs'
const tableData = ref([
{ code: 1, name: '项目1' },
{ code: 2, name: '项目2' },
{ code: 3, name: '项目3' }
])
// 添加数据方法
const handleAdd = () => {
const newData = {
code: Date.now(),
name: '新项目' + (tableData.value.length + 1)
}
tableData.value.push(newData)
}
// 记录滚动位置
const scrollTopTemp = ref(0)
onMounted(() => {
const el = document.querySelector('.el-table__body-wrapper tbody')
if (!el) return
Sortable.create(el, {
handle: '.drag-handle', // 拖拽句柄
animation: 150, // 动画过渡时间
onEnd({ newIndex, oldIndex }) {
const currRow = tableData.value.splice(oldIndex, 1)[0]
tableData.value.splice(newIndex, 0, currRow)
}
})
})
</script>
<style scoped>
.table-header {
margin-bottom: 20px;
}
.drag-handle {
cursor: move;
font-size: 20px;
color: #909399;
}
:deep(.el-table__row) {
cursor: move;
}
</style>
有时因为嵌套原因,或者循环创建会造成 序号不更新的情况
解决方法如下
onEnd({ newIndex, oldIndex }) {
const listTemp = [...tableData.value]
const currRow = listTemp.splice(oldIndex, 1)[0]
listTemp.splice(newIndex, 0, currRow)
// 使用 nextTick 确保数据更新后再设置滚动位置
tableData.value = []
nextTick(() => {
tableData.value = listTemp
})
}
该方法会解决序号刷新问题 但是会造成表格重置 导致 滚动条回到顶部
解决如下
Sortable.create(el, {
handle: '.drag-handle', // 拖拽句柄
animation: 150, // 动画过渡时间
onStart() {
// 记录滚动位置
// 这里需要注意你的滚动元素 是那个 我的是html标签
scrollTopTemp.value = document.documentElement.scrollTop
},
onEnd({ newIndex, oldIndex }) {
const currRow = tableData.value.splice(oldIndex, 1)[0]
tableData.value.splice(newIndex, 0, currRow)
// 使用 nextTick 确保数据更新后再设置滚动位置
tableData.value = []
nextTick(() => {
tableData.value = listTemp
nextTick(() => {
// 这里需要注意你的滚动元素 是那个 我的是html标签
document.documentElement.scrollTop = scrollTopTemp.value
})
})
}
})
-
注意:
弹窗中的表格拖拽 请在 每次弹窗打开后面进行初始化。
-
完成!