效果:
实现
<template>
<div class="box">
<div
v-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属性