实现组件间拖拽事件,并区分拖放区域(左上角、左下角、右上角、右下角),先定义两个基础组件。
DraggableItem 组件
这是一个可以拖拽的组件:
<template>
<div class="draggable-item" draggable="true" @dragstart="handleDragStart">
<p>{{ itemName }}</p>
</div>
</template>
<script>
export default {
props: {
itemName: String,
itemData: Object
},
methods: {
handleDragStart(event) {
event.dataTransfer.setData('text/plain', JSON.stringify(this.itemData));
}
}
};
</script>
<style scoped>
.draggable-item {
padding: 10px;
margin: 5px;
background-color: #f0f0f0;
border: 1px solid #ccc;
cursor: grab;
}
</style>
DropZone 组件
这是一个接收拖拽的区域:
<template>
<div class="drop-zone" @dragover="handleDragOver" @drop="handleDrop">
<slot></slot>
</div>
</template>
<script>
export default {
methods: {
handleDragOver(event) {
event.preventDefault();
},
handleDrop(event) {
event.preventDefault();
const data = event.dataTransfer.getData('text/plain');
const itemData = JSON.parse(data);
// 获取dropZone的bounding box
const dropZone = event.currentTarget.getBoundingClientRect();
// 计算鼠标位置相对于dropZone的位置
const x = event.clientX - dropZone.left;
const y = event.clientY - dropZone.top;
// 区分不同区域
const isLeft = x < dropZone.width / 2;
const isTop = y < dropZone.height / 2;
let region;
if (isLeft && isTop) {
region = '左上角';
} else if (isLeft && !isTop) {
region = '左下角';
} else if (!isLeft && isTop) {
region = '右上角';
} else {
region = '右下角';
}
console.log('Dropped item:', itemData, 'Region:', region);
this.$emit('item-dropped', { itemData, region });
}
}
};
</script>
<style scoped>
.drop-zone {
width: 100%;
height: 200px;
border: 2px dashed #ccc;
position: relative;
}
</style>
2. 组合组件
将 DraggableItem
和 DropZone
组件组合在一起,创建一个包含拖拽和放置功能的父组件。
<template>
<div class="app">
<div class="items">
<draggable-item
v-for="(item, index) in items"
:key="index"
:item-name="'Item ' + (index + 1)"
:item-data="item"
/>
</div>
<drop-zone @item-dropped="handleItemDropped">
<p>拖拽项目到此区域</p>
</drop-zone>
</div>
</template>
<script>
import DraggableItem from './components/DraggableItem.vue';
import DropZone from './components/DropZone.vue';
export default {
components: {
DraggableItem,
DropZone
},
data() {
return {
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' }
]
};
},
methods: {
handleItemDropped({ itemData, region }) {
console.log(`Item dropped: ${itemData.name} in ${region}`);
// 在此处理不同区域的逻辑
}
}
};
</script>
<style scoped>
.app {
display: flex;
justify-content: space-between;
padding: 20px;
}
.items {
width: 45%;
display: flex;
flex-direction: column;
}
.drop-zone {
width: 45%;
display: flex;
align-items: center;
justify-content: center;
}
</style>
当用户将 DraggableItem
组件拖拽到 DropZone
区域时,判断拖放位置,父组件监听 item-dropped
事件来处理不同区域的逻辑。