效果:
实现
<template><div class="box"><divv-for="(item, index) in items":key="item.id"class="item":style="{ order: item.order }":draggable="true"@dragstart="onDragStart(index)"@dragover.prevent="onDragOver"@drop="onDrop(index, $event)">{{ item.name }}</div></div>
</template><script setup>
import { ref } from "vue";const items = ref([{ id: 1, name: "Item 1", order: 1 },{ id: 2, name: "Item 2", order: 2 },{ id: 3, name: "Item 3", order: 3 },
]);
let draggedIndex = null;const onDragStart = (index) => {draggedIndex = index;
};const onDragOver = (event) => {event.preventDefault();
};const onDrop = (targetIndex, event) => {event.preventDefault();if (draggedIndex !== targetIndex) {const draggedOrder = items.value[draggedIndex].order;const targetOrder = items.value[targetIndex].order;items.value[draggedIndex].order = targetOrder;items.value[targetIndex].order = draggedOrder;}
};
</script><style>
.box {display: flex;flex-wrap: wrap;
}.item {width: 100px;height: 100px;border: 1px solid #ccc;background-color: #f3f3f3;margin: 5px;display: flex;justify-content: center;align-items: center;font-size: 16px;cursor: move;user-select: none;transition: background-color 0.3s;
}
.item:active {background-color: #ddd;
}
</style>
核心就是 flex布局 的 order属性