拖拽实现参考 sortablejs中文网 sortablejs官方实现参考
需求:实现列表行拖拽,比如将列表的第二行拖动到第一行,序号不变
1-安装:
npm install sortablejs
2-引入:
import Sortable from "sortablejs";
3-vue3+elementplus+sortablejs实现,代码如下:
保持拖拽后序号不变——最终用到了比对的方法(getRowNumber:比对当前的名称在拖拽后的数组中的序号,就修改当前序号)
详见代码具体逻辑:
<script setup lang="ts">
import { nextTick, ref, computed } from 'vue';
import type { FormInstance } from "element-plus";
import Sortable from "sortablejs";
const systemStore = useSystemStore();
// 表格数据展示 默认数据
const tableData = ref([
'自定义1', '自定义2', '自定义3', '自定义4',
'自定义5', '自定义6', '自定义7', '自定义8'
].map((name, index) => ({
id: String(index + 1),
name,
showName: name,
isShow: false
})));
// 拖拽之后的数组
const dragInfoArr = ref([...tableData.value]);
const tableDataRef = ref < FormInstance > ();
// 具体逻辑1——行拖拽实现
const rowDrop = () => {
nextTick(() => {
if (terminalInfoShowRef.value) {
const tableEl = tableDataRef.value.$el.querySelector('.el-table__body-wrapper tbody');
Sortable.create(tableEl, {
animation: 180,
delay: 0,
onEnd ({ newIndex, oldIndex }) {
//实现得到交换的数据
let dragItem = dragInfoArr.value.splice(oldIndex, 1);
dragInfoArr.value.splice(newIndex, 0, ...dragItem);
},
filter: '.disabled-drag'
})
}
});
}
//具体逻辑2——保持索引不变
const getRowNumber = (name) => {
// 在 dragInfoArr 中查找对应名字的项
const index = dragInfoArr.value.findIndex(item => item.name === name);
// 如果找到了对应项,则返回该项的索引值加一;否则返回 -1
return index !== -1 ? index + 1 : -1;
};
</script>
<template>
<div>
<el-table :data="tableData" :height="600" class="border border-solid border-[1px] border-[#eee]"
ref="tableDataRef"
:header-cell-style="{ background: 'rgba(240,243,245,0.39)',color: '#333', fontWeight: 'bold', fontSize: '12px' }"
empty-text="暂无数据" :cell-class-name="setCellClassName" use-virtual show-overflow-tooltip
showBodyOverflow="tooltip" showHeaderOverflow="title" tooltip-effect="light" highlight-current-row stripe
resizable>
<el-table-column label="序号" fixed="left" width="60">
<template #default="scope">
{{ getRowNumber(scope.row.name) }}
</template>
</el-table-column>
<el-table-column width="60" label="显示" align="center">
<template #default="scope">
<el-checkbox v-model="scope.row.isShow"></el-checkbox>
</template>
</el-table-column>
<el-table-column min-width="80" prop="name" label="属性" align="center" />
<el-table-column prop="showName" label="名称" min-width="120px">
<template #default="scope">
<el-input v-model="scope.row.showName" style="width:140px;"></el-input>
</template>
</el-table-column>
<el-table-column min-width="40" label="调整" fixed="right">
<template #default="scope">
<div class="p-[10px]" @mouseenter="rowDrop">
拖动调整
</div>
</template>
</el-table-column>
</el-table>
</div>
</template>