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 相关文章推荐
用js实现层随着内容大小动态渐变改变 推荐
Dec 19 Javascript
js写一个弹出层并锁屏效果实现代码
Dec 07 Javascript
document.createElement()用法及注意事项(ff下不兼容)
Mar 13 Javascript
JQuery 给元素绑定click事件多次执行的解决方法
Sep 09 Javascript
全面了解js中的script标签
Jul 04 Javascript
js中class的点击事件没有效果的解决方法
Oct 13 Javascript
Vue2.0如何发布项目实战
Jul 27 Javascript
jquery获取链接地址和跳转详解(推荐)
Aug 15 jQuery
使用vue制作FullPage页面滚动效果
Aug 21 Javascript
实例详解BootStrap的动态模态框及静态模态框
Aug 13 Javascript
layui当点击文本框时弹出选择框,显示选择内容的例子
Sep 02 Javascript
JavaScript中reduce()的用法
May 11 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
PHP中is_file()函数使用指南
2015/05/08 PHP
Zend Framework框架Smarty扩展实现方法
2016/03/22 PHP
PHP基于curl post实现发送url及相关中文乱码问题解决方法
2017/11/25 PHP
PHP有序表查找之插值查找算法示例
2018/02/10 PHP
js拖动div 当鼠标移动时整个div也相应的移动
2013/11/21 Javascript
js验证整数加保留小数点的简单实例
2013/12/02 Javascript
用console.table()调试javascript
2014/09/04 Javascript
Javascript学习笔记之数组的遍历和 length 属性
2014/11/23 Javascript
本人自用的global.js库源码分享
2015/02/28 Javascript
JavaScript通过select动态更换图片的方法
2015/03/23 Javascript
JS获取iframe中marginHeight和marginWidth属性的方法
2015/04/01 Javascript
简单的分页代码js实现
2016/05/17 Javascript
详解微信小程序——自定义圆形进度条
2016/12/29 Javascript
JavaScript实现元素滚动条到达一定位置循环追加内容
2017/12/28 Javascript
基于vue 动态菜单 刷新空白问题的解决
2020/08/06 Javascript
[58:32]EG vs Liquid 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
在Python下使用Txt2Html实现网页过滤代理的教程
2015/04/11 Python
Python回调函数用法实例详解
2015/07/02 Python
Python实现小数转化为百分数的格式化输出方法示例
2017/09/20 Python
Python如何生成树形图案
2018/01/03 Python
解决python nohup linux 后台运行输出的问题
2018/05/11 Python
查看django版本的方法分享
2018/05/14 Python
在Pycharm中执行scrapy命令的方法
2019/01/16 Python
Python+OpenCV采集本地摄像头的视频
2019/04/25 Python
Pandas之Dropna滤除缺失数据的实现方法
2019/06/25 Python
python删除列表元素的三种方法(remove,pop,del)
2019/07/22 Python
Tensorflow获取张量Tensor的具体维数实例
2020/01/19 Python
Python lambda表达式原理及用法解析
2020/08/18 Python
电子商务专业在校生实习自我鉴定
2013/09/29 职场文书
开办化妆品公司创业计划书
2013/12/26 职场文书
海南地接欢迎词
2014/01/14 职场文书
中专自我鉴定
2014/02/05 职场文书
社区母亲节活动记录
2014/03/06 职场文书
幼儿园中班区域活动总结
2014/07/09 职场文书
left join、inner join、right join的区别
2021/04/05 MySQL
Python实现智慧校园自动评教全新版
2021/06/18 Python