vue指令实现拖拽
Vue 指令实现拖拽功能
通过自定义指令或结合第三方库,可以轻松实现拖拽功能。以下是几种常见方法:
使用原生 HTML5 拖拽 API
通过 v-drag 自定义指令封装原生拖拽事件:
Vue.directive('drag', {
bind(el) {
el.setAttribute('draggable', true);
el.style.cursor = 'move';
el.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', el.id);
el.style.opacity = '0.5';
});
el.addEventListener('dragend', () => {
el.style.opacity = '1';
});
}
});
模板中使用:
<div v-drag>拖拽元素</div>
结合鼠标事件实现自由拖拽
通过 mousedown、mousemove 和 mouseup 事件实现更灵活的拖拽:

Vue.directive('free-drag', {
bind(el) {
let isDragging = false;
let offsetX, offsetY;
el.addEventListener('mousedown', (e) => {
isDragging = true;
offsetX = e.clientX - el.getBoundingClientRect().left;
offsetY = e.clientY - el.getBoundingClientRect().top;
el.style.position = 'absolute';
el.style.cursor = 'grabbing';
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
el.style.left = `${e.clientX - offsetX}px`;
el.style.top = `${e.clientY - offsetY}px`;
});
document.addEventListener('mouseup', () => {
isDragging = false;
el.style.cursor = 'grab';
});
}
});
使用第三方库 vue-draggable
对于列表排序等复杂场景,推荐使用 vue-draggable 库:
安装:

npm install vuedraggable
使用示例:
import draggable from 'vuedraggable';
export default {
components: { draggable },
data() {
return {
list: ['Item 1', 'Item 2', 'Item 3']
}
}
}
模板:
<draggable v-model="list">
<div v-for="(item, index) in list" :key="index">
{{ item }}
</div>
</draggable>
实现拖拽边界限制
通过计算边界值限制拖拽范围:
Vue.directive('bound-drag', {
bind(el, binding) {
const container = binding.value || document.body;
let isDragging = false;
let startX, startY;
el.addEventListener('mousedown', (e) => {
isDragging = true;
startX = e.clientX - el.offsetLeft;
startY = e.clientY - el.offsetTop;
});
container.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const maxX = container.clientWidth - el.clientWidth;
const maxY = container.clientHeight - el.clientHeight;
let left = e.clientX - startX;
let top = e.clientY - startY;
left = Math.max(0, Math.min(left, maxX));
top = Math.max(0, Math.min(top, maxY));
el.style.left = `${left}px`;
el.style.top = `${top}px`;
});
container.addEventListener('mouseup', () => {
isDragging = false;
});
}
});
这些方法覆盖了从基础到高级的拖拽场景,可根据具体需求选择合适方案。






