当前位置: 首页 > web >正文

4.x版本的ant-table+sortablejs实现拖拽排序

实现效果图:

遇到的问题:

因为功能需求,我需要在排序完后,再对排序后的tableData进行排序检查,因为,被锁的字段只能排在最前面,如果排序后的tableData的不符合要求则会对其进行重排序,将被锁的字段放在对前面。

但是现在的问题是,因为我进行了排序检查和二次排序,导致数据tableData确实是正确的,但是组件table确实不正确的。想来是因为DOM没有刷新,造成的。

直观的问题是,我将某个字段排序放到最后一个的时候,这个字段即会在最后一个显示也会在第一个显示。

我想到的解决办法是对table组件增加个key每次排序完后改变key,让table强制刷新。但是这也出现了第二个问题,每次强制刷新完table后滚动条就会重置到最顶端。这给用户的体验非常不好。

解决这个问题的办法也很简单,那就是使用原生的js,给table这个盒子增加个滚动监听事件,记录每次滚动的距离,再排完序强制刷新后再让table滚动到上次记录的位置就可以了(邪修)。这个滚动是在页面显示前就完成了不会造成闪烁问题。

代码:

<script setup>
import { LockOutlined, MenuOutlined, UnlockOutlined } from '@ant-design/icons-vue'
import Sortable from 'sortablejs'
import { nextTick, onUnmounted, ref } from 'vue'const props = defineProps({rowSelection: {type: Object,default: () => null,},tableData: {type: Array,default: () => ref([]),},
})
const emit = defineEmits(['dragMove', 'lock'])
const columns = [{title: '锁定',dataIndex: 'lock',align: 'center',width: 80,},{title: '列名',dataIndex: 'title',align: 'left',ellipsis: true,width: 240,},{title: '排序',dataIndex: 'id',align: 'center',},
]
const table = ref(null)
const keyValue = ref(0)
const scrollTop = ref(0)function setScroll(y) {const scrollContainer = table.value?.$el?.querySelector('.kgd-table-body')scrollContainer.scrollTop = y
}
function handleTableScroll(e) {scrollTop.value = e.target.scrollTop
}
function watchScroll() {const scrollContainer = table.value?.$el?.querySelector('.kgd-table-body')if (scrollContainer) {scrollContainer.addEventListener('scroll', handleTableScroll)}
}
function initSortable() {const tableSort = table.valuewatchScroll()// 另外一种获取方法const array = tableSort.$el.querySelectorAll('tbody') // 所有tobodySortable.create(array[0], {handle: '.drag-id',animation: 150,draggable: '.kgd-table-row',onEnd: ({ newIndex, oldIndex }) => {tableSort.$forceUpdate()if (newIndex !== oldIndex) {emit('dragMove', newIndex - 1, oldIndex - 1)keyValue.value++nextTick(() => {initSortable()})}},})nextTick(() => {setScroll(scrollTop.value)})
}function lock(row) {emit('lock', row)
}defineExpose({initSortable,
})onUnmounted(() => {const scrollContainer = table.value?.$el?.querySelector('.kgd-table-body')if (scrollContainer) {scrollContainer.removeEventListener('scroll', handleTableScroll)}
})
</script><template><a-tableref="table":key="keyValue"size="middle":row-selection="props.rowSelection":data-source="props.tableData":columns="columns":pagination="false"row-key="dataIndex":scroll="{ y: 'calc(100vh - 350px)' }"><template #bodyCell="{ column, record }"><template v-if="column.dataIndex === 'id'"><MenuOutlined v-if="record.fixed !== 'right'" class="drag-id" /></template><template v-if="column.dataIndex === 'lock'"><a v-if="record.fixed !== 'right'" class="btn_lock" @click="() => { lock(record) }"><LockOutlined v-if="record.fixed === 'left'" /><UnlockOutlined v-else style="color: #8e8e8e;" /></a></template></template></a-table>
</template><style scoped lang="less">
.drag-id {cursor: move;color: #00a578;
}
</style>

http://www.xdnf.cn/news/19134.html

相关文章:

  • 快速入门Vue3——语法初识
  • 如何给我们直接创建的类加上索引?和len方法?
  • 数字化生产管理系统 (MES)
  • WINTRUST!_ExplodeMessage的作用是赋值psIndirectData
  • Docker 是什么?
  • python自动化测试工具selenium使用指南
  • 在 Ubuntu 24.04 上安装二进制文件(逐步指南)
  • 模型汇总-数学建模
  • claude code helper for vscode
  • 用户模式与内核模式:操作系统的“权限双轨制”
  • 【C++游记】物种多样——谓之多态
  • 软考-系统架构设计师 决策支持系统(DSS)详细讲解
  • 序列化,应用层自定义协议
  • C#和Lua相互访问
  • 数据结构:冒泡排序 (Bubble Sort)
  • 配送算法17 AFramework for Multi-stage Bonus Allocation in meal delivery Platform
  • 嵌入式研发工程师成长路线图,基础入门 → 中级提升 → 高级进阶 → 专家方向
  • 【笔记ing】大模型算法架构
  • Ollama 是否适合生产环境部署支持业务总结
  • [ICCV25]TRACE:用3D高斯直接学习物理参数,让AI“推演”未来场景
  • UML状态图中entry/do/exit动作的深入解析与C/C++实现
  • C++学习笔记之异常处理
  • 驱动开发系列67 - NVIDIA 开源GPU驱动open-gpu-kernel-modules分析-驱动初始化
  • Redis实战-点赞的解决方案
  • CodeSouler v2.4.0 版本更新
  • 20250828_学习JumpServer开源堡垒机使用:统一访问入口 + 安全管控 + 操作审计
  • 8.28日QT
  • Linux并发与竞争
  • 专项智能练习(图形图像基础)
  • 97、23种设计模式之桥接模式(6/23)