开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第23天,点击查看活动详情
前言
今天遇到了表格拖拽功能,记录一下该功能的实现。效果如下
拖拽表格某一项时,出现不同的样式,结束拖拽后,按照最新的排序展示数据
表格拖拽实现
实现表格拖拽功能使用到了Sortable.js
安装Sortable.js
npm install sortablejs
新建article-ranking/sortable/index.js
,对sortable初始化,首先看Sortable.js
官网的demo,其中传入两个参数,第一个为拖拽对象,第二个为配置项
对比自己的结构
可以发现我需要获取到tbody
这个节点,我们导出一个配置方法,首先需要获取到tbody
节点,初始化传入的配置项中,ghostClass
表示为拖拽元素添加的类名,方便后面为这个拖拽项渲染不同的样式,onEnd
表示拖拽完成后执行的方法,这里暂时先不去处理里面的逻辑
还需要导出一个ref对象,和表格绑定在一起
import Sortable from 'sortablejs'
import { ref } from 'vue'
// 表格ref对象
export const tableRef = ref(null)
export const initSorttable = () => {
// 获取到tbody节点
const el = tableRef.value.$el.querySelectorAll(
'.el-table__body-wrapper > table > tbody'
)[0]
// 拖拽元素 配置对象
Sortable.create(el, {
// 拖拽时类名
ghostClass: 'sortable-ghost',
// 拖拽结束方法
onEnd(event) {}
})
}
<el-table ref="tableRef" :data="tableData" border>
接着在article-ranking.vue
中导入,在onMounted
中初始化
import { tableRef, initSortable } from './sortable'
// 表格拖拽相关
onMounted(() => {
initSortable()
})
并且为拖拽项加上样式
:deep(.sortable-ghost) {
opacity: 0.6;
color: #fff !important;
background: #304156 !important;
}
这样简单的拖拽效果就完成了,后面去处理拖拽完成后的逻辑
拖拽完成后
在onEnd
方法的event
参数中可以获取到拖拽项新的下标和原来的下标,获取到后调用接口重置表格数据的排序
export const initSorttable = (tableData) => {
···
onEnd(event) {
const { newIndex, oldIndex } = event
console.log(newIndex, oldIndex)
// 重置排序接口
articleSort({
initRanking: tableData[oldIndex].value.ranking,
finalRanking: tableData[newIndex].value.ranking
})
}
}
这里传入了tableData
而非tableData.value
,因为在挂载时数据为空,这时候传入的是空值,所以我们直接传入响应式数据,在article-ranking/sortable/index.js
中通过.value
的方式获取数据
const tableData = ref([])
// 初始化sortable
onMounted(() => {
initSorttable(tableData)
})
重置排序后,希望得到排序后最新的数据
我们传入获取数据的方法getListData
// 初始化sortable
onMounted(() => {
initSorttable(tableData, getListData)
})
接着在拖拽完成后先将tableData.value
赋空,在调用方法获取数据,如果不赋空的话,表格展示的还是拖拽完成后的排序,不是获取的最新排序的数据。最后提示信息即可
export const initSorttable = (tableData, callback) => {
···
onEnd(event) {
const { newIndex, oldIndex } = event
console.log(newIndex, oldIndex)
articleSort({
initRanking: tableData[oldIndex].value.ranking,
finalRanking: tableData[newIndex].value.ranking
})
tableData.value = []
callback && callback()
ElMessage.success(i18n.global.t('msg.article.sortSuccess'))
}
})
}