欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Vue使用自定义指令实现拖拽行为实例分析

程序员文章站 2024-01-17 13:55:40
本文实例讲述了vue使用自定义指令实现拖拽行为。分享给大家供大家参考,具体如下:需求通过自定义指令的方式实现拖拽效果,预期的使用方式为:

本文实例讲述了vue使用自定义指令实现拖拽行为。分享给大家供大家参考,具体如下:

需求

通过自定义指令的方式实现拖拽效果,预期的使用方式为:

<div style="background: #f00; width: 200px; height: 200px;" v-drag>
  xxxx
</div>

更重要的一个需求点:

  • 拖拽元素内部的子元素可以自行阻止拖拽行为

比如:

<div style="background: #f00; width: 200px; height: 200px;" v-drag>
   <el-button @mousedown.native.stop>test</el-button>
</div>

曾经使用过vue-resizable,由于该组件是通过事件捕获的方式实现的,拖拽元素的子元素也会触发拖拽行为,不符合开发需求,所以自行实现了拖拽指令,相关源码如下。

无任何依赖,复制即可使用

源码

/**
 * @file 自定义拖拽命令
 */
import vue from 'vue';
const drag = {
  install(vue: any) {
    // 如需禁止拖拽元素内部某些元素触发拖拽,在内部不可触发拖拽元素上添加@mousedown.native.stop即可
    vue.directive('drag', {
      bind(el: any) {
        el.style.position = 'absolute';
        el.style.zindex = el.style.zindex || '3000';
      },

      inserted(el: any) {
        // 设置元素初始位置
        const boundingclientrect = el.getboundingclientrect();
        el.style.left = boundingclientrect.x + 'px';
        el.style.top = boundingclientrect.y + 'px';
        // 将拖拽元素置于body子元素,防止被relative的父元素遮挡
        document.body.appendchild(el);

        let originx: number;
        let originy: number;
        const mousedownhandler = (evt: mouseevent) => {
          originx = evt.clientx - el.offsetleft;
          originy = evt.clienty - el.offsettop;
          el.style.cursor = 'pointer';
        };
        const mousemovehandler = (evt: mouseevent) => {
          if (evt.buttons === 1 && originx && originy) {
            el.style.left = evt.clientx - originx + 'px';
            el.style.top = evt.clienty - originy + 'px';
          }
        };
        const mouseuphandler = () => {
          el.style.cursor = 'default';
        };
        el.addeventlistener('mousedown', mousedownhandler);
        el.addeventlistener('mousemove', mousemovehandler);
        el.addeventlistener('mouseup', mouseuphandler);
        el.__mousedownhandler__ = mousedownhandler;
        el.__mousemovehandler__ = mousemovehandler;
        el.__mouseuphandler__ = mouseuphandler;
      },

      unbind(el: any) {
        el.removeeventlistener('mousedown', el.__mousedownhandler__);
        el.removeeventlistener('mousemove', el.__mousemovehandler__);
        el.removeeventlistener('mouseup', el.__mouseuphandler__);
        // 当父组件销毁触发unbind的时候需要手动删除这个节点,不然会一直存留在body中
        el.parentnode.removechild(el);
      }
    });
  }
};
vue.use(drag);
export default drag;

希望本文所述对大家vue.js程序设计有所帮助。