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关键字命名的疑问介绍
Apr 25 Javascript
仿JQuery输写高效JSLite代码的一些技巧
Jan 13 Javascript
JavaScript判断IE版本型号
Jul 27 Javascript
JavaScript的jQuery库插件的简要开发指南
Aug 12 Javascript
Bootstrap和Angularjs配合自制弹框的实例代码
Aug 24 Javascript
详解angularJs模块ui-router之状态嵌套和视图嵌套
Apr 28 Javascript
Vue 实现双向绑定的四种方法
Mar 16 Javascript
如何从零开始利用js手写一个Promise库详解
Apr 19 Javascript
微信小程序系列之自定义顶部导航功能
May 21 Javascript
JavaScript中将值转换为字符串的五种方法总结
Jun 06 Javascript
微信小程序 scroll-view 水平滚动实现过程解析
Oct 12 Javascript
JavaScript实现音乐播放器
Aug 14 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
phpMyAdmin2.11.6安装配置方法
2008/08/24 PHP
PHP学习之字符串比较和查找
2011/04/17 PHP
PHP 登录完成后如何跳转上一访问页面
2014/01/14 PHP
最新制作ThinkPHP3.2.3完全开发手册
2015/11/23 PHP
JavaScript 对话框和状态栏使用说明
2009/10/25 Javascript
js原型链原理看图说明
2012/07/07 Javascript
js+JQuery返回顶部功能如何实现
2012/12/03 Javascript
获取数组中最大最小值方法js代码(自写)
2013/08/12 Javascript
NodeJS学习笔记之Connect中间件应用实例
2015/01/27 NodeJs
JavaScript 匿名函数和闭包介绍
2015/04/13 Javascript
JS模态窗口返回值兼容问题的完美解决方法
2016/05/28 Javascript
JavaScript对象_动力节点Java学院整理
2017/06/23 Javascript
Async Validator 异步验证使用说明
2017/07/03 Javascript
详谈for循环里面的break和continue语句
2017/07/20 Javascript
Vue EventBus自定义组件事件传递
2018/06/25 Javascript
Vue.js watch监视属性知识点总结
2019/11/11 Javascript
JavaScript 实现HTML DOM增删改查操作的常见方法详解
2020/01/04 Javascript
javascript设计模式 ? 桥接模式原理与应用实例分析
2020/04/13 Javascript
Python处理PDF及生成多层PDF实例代码
2017/04/24 Python
python爬虫框架talonspider简单介绍
2017/06/09 Python
python+opencv实现霍夫变换检测直线
2020/10/23 Python
对python条件表达式的四种实现方法小结
2019/01/30 Python
对python 中class与变量的使用方法详解
2019/06/26 Python
python的debug实用工具 pdb详解
2019/07/12 Python
Python实现最常见加密方式详解
2019/07/13 Python
美国最佳选择产品网站:Best Choice Products
2019/05/27 全球购物
在Java开发中如何选择使用哪种集合类
2016/08/09 面试题
大学毕业登记表自我鉴定
2013/10/09 职场文书
片区教研活动总结
2014/07/02 职场文书
2015年党日活动总结范文
2015/03/25 职场文书
2019财务毕业实习报告
2019/06/27 职场文书
Golang 空map和未初始化map的注意事项说明
2021/04/29 Golang
Spring Boot 实现敏感词及特殊字符过滤处理
2021/06/29 Java/Android
Redis实战高并发之扣减库存项目
2022/04/14 Redis
解决IDEA翻译插件Translation报错更新TTK失败不能使用
2022/04/24 Python
python库Tsmoothie模块数据平滑化异常点抓取
2022/06/10 Python