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让指定的元素闪烁显示的方法
Mar 17 Javascript
Javascript使用post方法提交数据实例
Aug 03 Javascript
jQuery实现带水平滑杆的焦点图动画插件
Mar 08 Javascript
window.onload绑定多个事件的两种解决方案
May 15 Javascript
PhotoSwipe异步动态加载图片方法
Aug 25 Javascript
vue2.0在table中实现全选和反选的示例代码
Nov 04 Javascript
Bootstrap4如何定制自己的颜色和风格
Feb 26 Javascript
解决bootstrap中下拉菜单点击后不关闭的问题
Aug 10 Javascript
vue使用laydate时间插件的方法
Nov 14 Javascript
JS实现求5的阶乘示例
Jan 21 Javascript
react写一个select组件的实现代码
Apr 03 Javascript
ES2020 已定稿,真实场景案例分析
May 25 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
转生史莱姆:萌王第一次撸串开心到飞起,哥布塔撸串却神似界王神
2018/11/30 日漫
php4的彩蛋
2006/10/09 PHP
判断php数组是否为索引数组的实现方法
2013/06/13 PHP
解析linux下安装memcacheq(mcq)全过程笔记
2013/06/27 PHP
PHP不用递归实现无限分级的例子分享
2014/04/18 PHP
Yii中使用PHPExcel导出Excel的方法
2014/12/26 PHP
PHP实现恶意DDOS攻击避免带宽占用问题方法
2015/05/27 PHP
PHP设计模式概论【概念、分类、原则等】
2020/05/01 PHP
Mootools 1.2教程 输入过滤第二部分(字符串)
2009/09/15 Javascript
小议javascript 设计模式 推荐
2009/10/28 Javascript
js 函数调用模式小结
2011/12/26 Javascript
eval的两组性能测试数据
2012/08/17 Javascript
JavaScript实现函数返回多个值的方法
2015/06/09 Javascript
jquery实现浮动的侧栏实例
2015/06/25 Javascript
jquery+CSS3实现淘宝移动网页菜单效果
2015/08/31 Javascript
Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(一)
2015/12/10 Javascript
实例解析Array和String方法
2016/12/14 Javascript
微信小程序学习(4)-系统配置app.json详解
2017/01/12 Javascript
jquery 仿锚点跳转到页面指定位置的实例
2017/02/14 Javascript
使用rollup打包JS的方法步骤
2018/12/05 Javascript
详解小程序云开发攻略(解决最棘手的问题)
2019/09/30 Javascript
vue mvvm数据响应实现
2020/11/11 Javascript
基于Vue3.0开发轻量级手机端弹框组件V3Popup的场景分析
2020/12/30 Vue.js
python连接mysql实例分享
2016/10/09 Python
python 文件操作删除某行的实例
2017/09/04 Python
Python设计模式之MVC模式简单示例
2018/01/10 Python
Python判断两个文件是否相同与两个文本进行相同项筛选的方法
2019/03/01 Python
Python人工智能之路 jieba gensim 最好别分家之最简单的相似度实现
2019/08/13 Python
Python 读取xml数据,cv2裁剪图片实例
2020/03/10 Python
生态养殖创业计划书
2014/05/06 职场文书
书香家庭事迹材料
2014/05/09 职场文书
医院安全生产月活动总结
2014/07/05 职场文书
夫妻双方自愿离婚协议书
2014/10/24 职场文书
目标责任书格式范文
2015/05/11 职场文书
正则表达式拆分url实例代码
2022/02/24 Java/Android
Python+OpenCV实现在图像上绘制矩形
2022/03/21 Python