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


Posted in Javascript onJune 06, 2020

本文实例讲述了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程序设计有所帮助。

Javascript 相关文章推荐
jquery ajax执行后台方法
Mar 18 Javascript
javascript实现禁止右键和F12查看源代码
Dec 26 Javascript
JavaScript中的类与实例实现方法
Jan 23 Javascript
实例解析jQuery工具函数
Dec 01 Javascript
AngularJS表格样式简单设置方法示例
Mar 03 Javascript
js弹出窗口简单实现代码
Mar 22 Javascript
微信小程序-横向滑动scroll-view隐藏滚动条
Apr 20 Javascript
详解在Angularjs中ui-sref和$state.go如何传递参数
Apr 24 Javascript
详解Angular路由之路由守卫
May 10 Javascript
微信小程序之判断页面滚动方向的示例代码
Aug 30 Javascript
vue集成kindeditor富文本的实现示例代码
Jun 07 Javascript
小程序wx.getUserProfile接口的具体使用
Jun 02 Javascript
JS原型对象操作实例分析
Jun 06 #Javascript
JS中的继承操作实例总结
Jun 06 #Javascript
ES6 async、await的基本使用方法示例
Jun 06 #Javascript
JS 数组和对象的深拷贝操作示例
Jun 06 #Javascript
ES6 Generator基本使用方法示例
Jun 06 #Javascript
jquery.validate自定义验证用法实例分析【成功提示与择要提示】
Jun 06 #jQuery
ES6 Symbol在对象中的作用实例分析
Jun 06 #Javascript
You might like
有关JSON以及JSON在PHP中的应用
2010/04/09 PHP
如何给phpcms v9增加类似于phpcms 2008中的关键词表
2013/07/01 PHP
PHP四大安全策略
2014/03/12 PHP
PHP中的替代语法介绍
2015/01/09 PHP
关于安卓手机微信浏览器中使用XMLHttpRequest 2上传图片显示字节数为0的解决办法
2016/05/17 Javascript
JS不用正则验证输入的字符串是否为空(包含空格)的实现代码
2016/06/14 Javascript
js获取指定字符前/后的字符串简单实例
2016/10/27 Javascript
Javascript blur与click冲突解决办法
2017/01/09 Javascript
JavaScript函数表达式详解及实例
2017/05/05 Javascript
jQuery实现简单的滑动导航代码(移动端)
2017/05/22 jQuery
javascript 中select框触发事件过程的分析
2017/08/01 Javascript
如何解决React官方脚手架不支持Less的问题(小结)
2018/09/12 Javascript
AngularJS修改model值时,显示内容不变的实例
2018/09/13 Javascript
微信小程序实现Session功能及无法获取session问题的解决方法
2019/05/07 Javascript
JavaScript 变量,数据类型基础实例详解【变量、字符串、数组、对象等】
2020/01/04 Javascript
Javascript执行上下文顺序的深入讲解
2020/11/04 Javascript
nuxt 路由、过渡特效、中间件的实现代码
2020/11/06 Javascript
python多线程用法实例详解
2015/01/15 Python
Python文档生成工具pydoc使用介绍
2015/06/02 Python
Python中字符串的处理技巧分享
2016/09/17 Python
pip安装Python库时遇到的问题及解决方法
2017/11/23 Python
使用Python+Splinter自动刷新抢12306火车票
2018/01/03 Python
django.db.utils.ProgrammingError: (1146, u“Table‘’ doesn’t exist”)问题的解决
2018/07/13 Python
Django中的cookie和session
2019/08/27 Python
Python利用PyPDF2库获取PDF文件总页码实例
2020/04/03 Python
Python实现列表索引批量删除的5种方法
2020/11/16 Python
CSS3 clip-path 用法介绍详解
2018/03/01 HTML / CSS
急诊科护士自我鉴定
2013/10/14 职场文书
难忘的一天教学反思
2014/04/30 职场文书
缅怀先烈演讲稿
2014/09/03 职场文书
2014年人事工作总结范文
2014/11/19 职场文书
跑吧孩子观后感
2015/06/10 职场文书
会议新闻稿
2015/07/17 职场文书
优质服务心得体会(共4篇)
2016/01/22 职场文书
vue中data改变后让视图同步更新的方法
2021/03/29 Vue.js
详解Go语言中Get/Post请求测试
2022/06/01 Golang