使用原生HTML的drag实现元素的拖拽
HTML 拖放(Drag and Drop)接口使应用程序能够在浏览器中使用拖放功能。例如,用户可使用鼠标选择可拖拽(draggable)元素,将元素拖拽到可放置(droppable)元素,并释放鼠标按钮以放置这些元素。拖拽操作期间,会有一个可拖拽元素的半透明快照跟随着鼠标指针。🔍MDN: HTML 拖放 API
1.draggable
属性:设置元素可以拖拽。true 表示元素可以被拖动,false 表示元素不可以被拖动。
注意:像 <img draggable>
这样的简写是不允许的。正确的用法是 <img draggable="true">
。
2.@dragstart
:在拖拽开始时,将当前拖拽项的索引存储到 draggedIndex,并设置拖拽光标的效果为 move
。更新 draggedIndex 实现拖拽过程中的预览。
3.@dragover.prevent
:当拖拽项经过其他项时,通过 splice 方法将当前拖拽项临时移除并插入到新的位置。
4.@drop
:当拖拽放置完成时,draggedIndex 被重置,以防止任何临时变化影响最终顺序。
案例代码:
<template>
<div class="drag-container">
<div
v-for="(item, index) in items"
:key="item.id"
class="draggable-item"
draggable="true"
:class="{ selected: index === draggedIndex }"
@dragstart="onDragStart($event, index)"
@dragover.prevent="onDragOver(index)"
@drop="onDrop(index)"
>
{{ item.name }}
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
// 定义拖拽的数据
const items = ref([
{ id: 1, name: "项 1" },
{ id: 2, name: "项 2" },
{ id: 3, name: "项 3" },
{ id: 4, name: "项 4" },
]);
// 用于存储当前被拖拽的元素的索引
const draggedIndex = ref(null);
// 拖拽开始事件
const onDragStart = (event, index) => {
draggedIndex.value = index;
// 设置拖拽光标效果
event.dataTransfer.effectAllowed = "move";
console.log(`开始拖拽: ${items.value[index].name}`);
};
// 拖拽经过目标时,临时预览排序效果
const onDragOver = (index) => {
if (draggedIndex.value !== null && draggedIndex.value !== index) {
//用 splice 方法将拖拽的项从原来的位置移除,并插入到新的位置
const draggedItem = items.value.splice(draggedIndex.value, 1)[0];
// 将 draggedItem 插入到 items 数组的 index 位置,从而实现排序的效果。
items.value.splice(index, 0, draggedItem);
// 更新 draggedIndex 以匹配新的位置
draggedIndex.value = index;
}
};
// 拖拽放置事件
const onDrop = (index) => {
// 拖拽完成后将索引重置
draggedIndex.value = null;
console.log(`放置到: ${items.value[index].name}`);
};
</script>
<style scoped>
.drag-container {
margin-left: 30px;
width: 100px;
display: flex;
flex-direction: column;
gap: 10px;
margin-top: 20px;
}
.draggable-item {
padding: 10px;
background-color: #4caf50;
color: white;
cursor: grab;
text-align: center;
}
/* 选中的拖拽项样式 */
.selected {
border: 2px dashed #ff9800;
}
</style>
在vue中还可以使用第三方库vuedraggable
来实现拖拽:🔍vue3使用vuedraggable实现拖拽(有过渡)