vue3 vite 使用指令方式拖拽元素(v-drag)以及指令权限(v-permission)等

📅 2026/8/22 11:19:15
vue3 vite 使用指令方式拖拽元素(v-drag)以及指令权限(v-permission)等
直接上代码1、在src/utils/drag.js中的内容如下exportconstdrag{mounted(el){el.style.cursormoveel.style.positionabsolute// 或者 fixedel.style.userSelectnone// 防止选中文本letstartX0letstartY0letinitialLeft0letinitialTop0// 鼠标按下事件el.addEventListener(mousedown,(e){// show_pointerconsole.log(show_pointer,e.target.className)if(e.target.className.includes(show_pointer)){el.style.cursorpointerreturn;}else{el.style.cursormove}// 如果点击的是 input 或 textarea则不触发拖拽if(e.target.tagNameINPUT||e.target.tagNameTEXTAREA){return}e.preventDefault()// 记录初始位置startXe.clientX startYe.clientY// 获取元素当前的位置initialLeftel.offsetLeft initialTopel.offsetTop// 添加移动和释放事件的监听document.addEventListener(mousemove,onMouseMove)document.addEventListener(mouseup,onMouseUp)// 防止选中文本document.body.style.userSelectnone})// 鼠标移动事件constonMouseMove(e){constdxe.clientX-startXconstdye.clientY-startY// 更新元素位置el.style.left${initialLeftdx}pxel.style.top${initialTopdy}px}// 鼠标释放事件constonMouseUp(){// 移除事件监听document.removeEventListener(mousemove,onMouseMove)document.removeEventListener(mouseup,onMouseUp)// 恢复文本选择document.body.style.userSelect}}}exportconsttitle_drag{mounted(el){el.style.cursormoveel.style.userSelectnone// 防止选中文本letstartX0letstartY0letinitialLeft0letinitialTop0letcenter_startX0letcenter_startY0letcenter_initialLeft0letcenter_initialTop0letcenter_domdocument.getElementById(wrap_center)console.log(center_dom,center_dom)center_dom.style.positionabsolute// 或者 fixedcenter_dom.style.userSelectnone// 鼠标按下事件el.addEventListener(mousedown,(e){e.preventDefault()// 记录初始位置startXe.clientX startYe.clientY// 获取元素当前的位置initialLeftel.offsetLeft initialTopel.offsetTop center_startXe.clientX center_startYe.clientY center_initialLeftcenter_dom.offsetLeft center_initialTopcenter_dom.offsetTop// 添加移动和释放事件的监听document.addEventListener(mousemove,onMouseMove)document.addEventListener(mouseup,onMouseUp)// 防止选中文本document.body.style.userSelectnone})// 鼠标移动事件constonMouseMove(e){constdxe.clientX-startXconstdye.clientY-startY center_dom.style.left${center_initialLeftdx}pxcenter_dom.style.top${center_initialTopdy}px}// 鼠标释放事件constonMouseUp(){// 移除事件监听document.removeEventListener(mousemove,onMouseMove)document.removeEventListener(mouseup,onMouseUp)// 恢复文本选择document.body.style.userSelect}}}exportconstconfind_drag{mounted(el){el.style.cursormoveel.style.userSelectnone// 防止选中文本letstartX0letstartY0letinitialLeft0letinitialTop0letcenter_startX0letcenter_startY0letcenter_initialLeft0letcenter_initialTop0letcenter_domdocument.getElementById(wrap_confind_watch)console.log(center_dom,center_dom)center_dom.style.positionabsolute// 或者 fixedcenter_dom.style.userSelectnone// 鼠标按下事件el.addEventListener(mousedown,(e){e.preventDefault()// 记录初始位置startXe.clientX startYe.clientY// 获取元素当前的位置initialLeftel.offsetLeft initialTopel.offsetTop center_startXe.clientX center_startYe.clientY center_initialLeftcenter_dom.offsetLeft center_initialTopcenter_dom.offsetTop// 添加移动和释放事件的监听document.addEventListener(mousemove,onMouseMove)document.addEventListener(mouseup,onMouseUp)// 防止选中文本document.body.style.userSelectnone})// 鼠标移动事件constonMouseMove(e){constdxe.clientX-startXconstdye.clientY-startY center_dom.style.left${center_initialLeftdx}pxcenter_dom.style.top${center_initialTopdy}px}// 鼠标释放事件constonMouseUp(){// 移除事件监听document.removeEventListener(mousemove,onMouseMove)document.removeEventListener(mouseup,onMouseUp)// 恢复文本选择document.body.style.userSelect}}}exportconstmini_map_drag{mounted(el){el.style.cursormoveel.style.userSelectnone// 防止选中文本letstartX0letstartY0letinitialLeft0letinitialTop0letcenter_startX0letcenter_startY0letcenter_initialLeft0letcenter_initialTop0letcenter_domdocument.getElementById(mini_map_title)center_dom.style.positionabsolute// 或者 fixedcenter_dom.style.userSelectnone// 鼠标按下事件el.addEventListener(mousedown,(e){e.preventDefault()// 记录初始位置startXe.clientX startYe.clientY// 获取元素当前的位置initialLeftel.offsetLeft initialTopel.offsetTop center_startXe.clientX center_startYe.clientY center_initialLeftcenter_dom.offsetLeft center_initialTopcenter_dom.offsetTop// 添加移动和释放事件的监听document.addEventListener(mousemove,onMouseMove)document.addEventListener(mouseup,onMouseUp)// 防止选中文本document.body.style.userSelectnone})// 鼠标移动事件constonMouseMove(e){constdxe.clientX-startXconstdye.clientY-startY center_dom.style.left${center_initialLeftdx}pxcenter_dom.style.top${center_initialTopdy}px}// 鼠标释放事件constonMouseUp(){// 移除事件监听document.removeEventListener(mousemove,onMouseMove)document.removeEventListener(mouseup,onMouseUp)// 恢复文本选择document.body.style.userSelect}}}2、在main.js中导入并注入vue中import./assets/main.cssimport{confind_drag,drag,title_drag,mini_map_drag}from/utils/drag.jsimport{createApp}fromvueimport{createPinia}frompiniaimportAppfrom./App.vueimportrouterfrom./routerconstappcreateApp(App)app.use(createPinia())app.use(router)app.directive(drag,drag)app.directive(title_drag,title_drag)app.mount(#app)3、在.vue文件中使用指令templatediv v-dragclassouterdivclassinnerhello-world/div/div/templatescript setupimport{ref}fromvue/scriptstyle scoped.outer{width:200px;height:200px;background-color:pink;}/style效果展示鼠标放上去可以随便拖拽v-title_drag的用法如下v-title_drag所在标签的父元素用写上idwrap_center即可当拖拽 v-title_drag所在的元素以及其子元素时父元素也被一起拖拽走templatediv idwrap_centerclassouterdiv v-title_dragclassinnerhello-world/div/div/templatescript setupimport{ref}fromvue/scriptstyle scoped.outer{width:200px;height:200px;background-color:pink;}/style