弹窗拖拽-指令
小于 1 分钟
弹窗拖拽-指令
创建指令
// directives/v-draggable.js
/**
* 自定义拖拽指令
*/
export default {
bind(el) {
let isDragging = false;
let startX, startY, offsetX, offsetY;
// 在mousedown事件上开始拖拽
el.addEventListener('mousedown', (e) => {
isDragging = true;
startX = e.clientX;
startY = e.clientY;
// 禁止文本选中,避免拖拽时出现不必要的选择效果
document.body.style.userSelect = 'none';
// 添加鼠标移动和鼠标抬起事件监听
const onMouseMove = (e) => {
if (isDragging) {
offsetX = e.clientX - startX;
offsetY = e.clientY - startY;
// 更新元素位置
el.style.left = `${el.offsetLeft + offsetX}px`;
el.style.top = `${el.offsetTop + offsetY}px`;
startX = e.clientX;
startY = e.clientY;
}
};
const onMouseUp = () => {
isDragging = false;
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
// 恢复文本选中
document.body.style.userSelect = '';
};
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
});
}
};
调用
全局注册 (
main.js)import Vue from 'vue'; import App from './App.vue'; import vDraggable from './directives/v-draggable'; // 导入自定义指令 // 注册指令 Vue.directive('draggable', vDraggable); new Vue({ render: h => h(App), }).$mount('#app');局部注册
<template> <div> <!-- 使用局部注册的指令 v-draggable --> <div v-draggable class="draggable-box"> <p>拖拽我!</p> </div> </div> </template> <script> // 导入你写的拖拽指令 import vDraggable from './directives/v-draggable'; export default { name: 'DraggableComponent', directives: { draggable: vDraggable // 局部注册指令 } }; </script> <style scoped> .draggable-box { position: absolute; width: 200px; height: 150px; background-color: #f0f0f0; border: 1px solid #ccc; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); padding: 10px; cursor: move; } </style>