话不多说代码复制直接运行看效果
一、table行拖拽并改变数组顺序
<template>
<el-table :data="dataList" style="width: 100%" :row-class-name="activeClass" class="outputTable">
<el-table-column prop="id" label="ID" width="120" />
<el-table-column prop="name" label="Name" width="120" />
<el-table-column prop="date" label="Date" width="120" />
<el-table-column prop="address" label="Address" />
<el-table-column label="操作1">
<template #default="$index">
<el-button link type="primary" @click="tuozuai($index)">
点击后拖拽排序
</el-button>
</template>
</el-table-column>
<el-table-column label="操作2">
<template #default="$index">
<el-button link @mouseenter="enableDrag($index)" @mouseleave="disableDrag($index)">
鼠标悬停拖拽排序
</el-button>
</template>
</el-table-column>
</el-table>
</template>
<script lang="ts" setup>
import { nextTick, ref } from 'vue';
const dataList = ref<any>([
{
id:'1',
date: "2024-07-01",
name: "Name1",
address: "贵州省",
},
{
id:'2',
date: "2024-07-02",
name: "Name2",
address: "贵州省",
},
{
id:'3',
date: "2024-07-03",
name: "Name3",
address: "重庆市",
},
{
id:'4',
date: "2024-07-04",
name: "Name4",
address: "重庆市",
},
]);
const dragIndex = ref<any>();
const newDragIndex = ref<any>();
const activeClass = ({ row, rowIndex }) => {
if (rowIndex === newDragIndex.value) {
return "isDragBox active-drag";
}
return "isDragBox";
};
const dragStartItem = (idx) => {
dragIndex.value = idx;
};
const dragOverItem = (index) => {
newDragIndex.value = index;
};
const dragEndItem = () => {
const data = dataList.value[dragIndex.value];
dataList.value.splice(dragIndex.value, 1);
dataList.value.splice(newDragIndex.value, 0, data);
dataList.value.forEach((item, index) => {
return (item.sort = index);
});
};
const handleSort = ( j = "", istrue =true) => {
nextTick(() => {
const dragBox = document.querySelectorAll(".outputTable .isDragBox");
dragBox.forEach((i: any, idx) => {
if(istrue){
i.setAttribute("draggable", "true");
i.ondragstart = () => dragStartItem(idx);
i.ondragover = () => dragOverItem(idx);
i.ondragend = () => dragEndItem();
}
else{
i.setAttribute("draggable", "false");
}
});
});
};
//鼠标点击 “点击后拖拽排序”后拖动
const tuozuai=(num)=>{
handleSort()
};
// 鼠标悬停启用拖拽
function enableDrag(a) {
handleSort(a)
};
// 鼠标离开禁用拖拽
function disableDrag(a) {
handleSort(a, false)
};
</script>
运行后页面
二、列表拖动
<template>
<ul>
<li
v-for="(item, index) in list"
:key="item.id"
:ref="setDraggableRef"
@dragstart="dragStart(index)"
@dragover.prevent
@dragenter="dragEnter(index)"
@dragend="dragEnd"
draggable="true"
>
{{ item.text }}
</li>
</ul>
</template>
<script>
import { ref, reactive, onMounted } from 'vue';
export default {
setup() {
const list = reactive([
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' },
// ...
]);
const draggableRefs = ref([]);
const dragData = reactive({
draggedIndex: null,
hoverIndex: null,
});
const setDraggableRef = (el, index) => {
if (el) {
draggableRefs.value[index] = el;
}
};
const dragStart = (index) => {
dragData.draggedIndex = index;
};
const dragEnter = (index) => {
dragData.hoverIndex = index;
};
const dragEnd = () => {
if (dragData.draggedIndex !== null && dragData.hoverIndex !== null) {
const draggedItem = list[dragData.draggedIndex];
list.splice(dragData.draggedIndex, 1);
list.splice(dragData.hoverIndex, 0, draggedItem);
}
dragData.draggedIndex = null;
dragData.hoverIndex = null;
};
onMounted(() => {
// 确保所有的列表项都是可拖动的
draggableRefs.value.forEach((el) => {
el.draggable = true;
});
});
return {
list,
setDraggableRef,
dragStart,
dragEnter,
dragEnd,
};
},
};
</script>