使用TypeScript给Vue 3.0写一个指令实现组件拖拽

网友投稿 646 2022-10-17

使用TypeScript给Vue 3.0写一个指令实现组件拖拽

使用TypeScript给Vue 3.0写一个指令实现组件拖拽

早上运维突然跑过来问我,为啥弹窗挡住了下边的表格的数据,我添加的时候,都没法对照表格来看了。你必须给我解决一下。

我参考了一下几大Vue的ui组件库。发现element iview antv。好像都没这个功能。为啥运维需要这个功能??

但是没办法,只能整一个就是了。

做之前本来想直接做到dialog这个组件中。但是又担心后面其他的组件会用到。于是决定把拖拽功能做到指令中。

整个功能点如图。鼠标在拖拽区域拖动,整个对话框在浏览器可视范围内移动。

Drag指令主要实现思路

let x = e.clientX; let y = e.clientY;

如何限制拖动的节点只能在屏幕内移动,不能移动出屏幕呢?

限制left不能小于0,在定位为position: fixed 的时候,left如果小于0,那么html节点的左侧肯定已经在显示区域外了。那么我们不能让left小于0

let bodyW = document.body.clientWidth; let bodyH = document.body.clientHeight; let left = elLeft - (x - move.clientX); if (left < 0) { left = 0; }

限制left不能大于可视区域的宽度减去当前html节点的宽度,如果left大于这个宽度,那么当前html节点肯定右侧已经处于显示区域的右侧外边了

if (left > bodyW - el.offsetWidth) { left = bodyW - el.offsetWidth; }

上下拖拽位置限制和左右拖拽限制思路是一样,只要保证top的值大于0且小于屏幕可视范围的高度减去当前html节点的高度,那么拖动就无法拖出屏幕了。

let top = elTop - (y - move.clientY); if (top < 0) { top = 0; } if (top > bodyH - el.offsetHeight) { top = bodyH - el.offsetHeight }

drag指令完整代码

import { App } from 'vue'; export default { install(Vue: App) { Vue.directive('drag', { mounted(el: HTMLElement, bind) { el.onmousedown = (e) => { let elLeft = el.offsetLeft; let elTop = el.offsetTop; let dom = e.target; if (dom.classList.contains('drag-target')) { let x = e.clientX; let y = e.clientY; document.onmousemove = (move: MouseEvent) => { let bodyW = document.body.clientWidth; let bodyH = document.body.clientHeight; let left = elLeft - (x - move.clientX); if (left < 0) { left = 0; } if (left > bodyW - el.offsetWidth) { left = bodyW - el.offsetWidth; } el.style.left = left + 'px' let top = elTop - (y - move.clientY); if (top < 0) { top = 0; } if (top > bodyH - el.offsetHeight) { top = bodyH - el.offsetHeight } el.style- = top + 'px' document.onmouseup = (up: MouseEvent) => { document.onmousemove = null; document.onmouseup = null } if (window.getSelection()) { window.getSelection()?.removeAllRanges() } } } } }, unmounted(el, bind) { el.onmousedown = null; } }) } }

使用

import DragDirective from './DragDirective' createApp(App).use(DragDirective).mount('#app')

注册指令到Vue App上,然后在需要移动的html节点上加上 v-drag ,并在触发拖拽的子节点的class上,加上drag-target

{{ title }}

效果图

早上运维突然跑过来问我,为啥弹窗挡住了下边的表格的数据,我添加的时候,都没法对照表格来看了。你必须给我解决一下。

我参考了一下几大Vue的ui组件库。发现element iview antv。好像都没这个功能。为啥运维需要这个功能??

但是没办法,只能整一个就是了。

做之前本来想直接做到dialog这个组件中。但是又担心后面其他的组件会用到。于是决定把拖拽功能做到指令中。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:spring注解 @PropertySource配置数据源全流程
下一篇:ChaosBlog- 静态博客输出程序
相关文章

 发表评论

暂时没有评论,来抢沙发吧~