
在 Vue Draggable 中,应使用 @move 事件(而非原生 @drag)获取拖拽中元素的精确位置;事件对象中的 draggedRect 属性提供了包含 x、y、top、left 等字段的 DOMRect 对象,可直接用于定位计算。
在 vue draggable 中,应使用 `@move` 事件(而非原生 `@drag`)获取拖拽中元素的精确位置;事件对象中的 `draggedrect` 属性提供了包含 `x`、`y`、`top`、`left` 等字段的 domrect 对象,可直接用于定位计算。
Vue Draggable(基于 SortableJS)为拖拽交互提供了语义化、组件级的事件系统。与原生 DOM 的 drag 事件不同,@drag 在该组件中实际绑定的是浏览器原生拖放事件(dragstart/drag),它不提供被拖元素在页面中的实时几何信息,仅能访问鼠标坐标(如 clientY),无法准确反映元素自身的位置——尤其在滚动容器、缩放或复杂布局下极易失准。
正确做法是监听组件自定义的 @move 事件。该事件在拖拽过程中高频触发,其回调参数是一个结构化的 MoveEvent 对象,关键属性包括:
-
dragged: 当前正在拖拽的 DOM 元素(HTMLElement) -
draggedRect: 该元素当前的布局矩形(DOMRect),含x,y,top,left,width,height,bottom,right等只读属性 -
to/from: 目标与源列表容器元素 -
related/relatedRect: 当前悬停/吸附的目标元素及其位置
因此,若需获取拖拽卡片顶部边缘在视口中的 Y 坐标(例如用于日历时间轴对齐判断),应直接读取 event.draggedRect.top 或 event.draggedRect.y:
<script setup>
import { ref } from 'vue'
import draggable from 'vuedraggable'
const appointments = ref([
{ id: 1, title: 'Meeting', time: '09:00' },
{ id: 2, title: 'Lunch', time: '12:30' }
])
function onDragMove(event) {
// ✅ 正确:获取拖拽元素上边缘在视口中的绝对 Y 坐标
const topPosition = event.draggedRect.top
console.log('Dragged element top (viewport Y):', topPosition)
// ✅ 同样有效:x/y 是 left/top 的别名(CSS 逻辑坐标)
console.log('X:', event.draggedRect.x, 'Y:', event.draggedRect.y)
// ✅ 获取完整尺寸信息,便于边界检测
console.log('Width:', event.draggedRect.width, 'Height:', event.draggedRect.height)
}
</script>
<template>
<div class="calendar-day">
<draggable
v-model="appointments"
tag="ol"
item-key="id"
@move="onDragMove" <!-- ? 使用 @move 替代 @drag -->
>
<template #item="{ element }">
<li class="appointment-card">{{ element.title }}</li>
</template>
</draggable>
</div>
</template>⚠️ 注意事项:
立即学习“前端免费学习笔记(深入)”;
-
@move事件仅在拖拽过程中持续触发,当拖拽结束(释放)时会触发@end,此时draggedRect仍有效,但不再更新; -
draggedRect基于getBoundingClientRect(),返回的是相对于视口(viewport) 的坐标,若需文档坐标(如配合document.elementFromPoint),可结合window.scrollY补偿:event.draggedRect.top + window.scrollY; - 确保
draggable组件已正确安装并注册(Vue 3 +<script setup></script>下推荐使用vuedraggable@next); - 若需高性能监听(如每帧计算),注意避免在
@move中执行重绘操作或复杂逻辑,必要时可用requestAnimationFrame节流。
通过 @move 和 draggedRect,你可精准实现日历中事件卡片按时间轴吸附、跨时段高亮提示、动态插入占位符等高级交互,真正掌控拖拽体验的底层空间语义。


















