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 相关文章推荐
论坛特效代码收集(落伍转发-不错)
Dec 02 Javascript
js类的静态属性和实例属性的理解
Oct 01 Javascript
javascript 图片上一张下一张链接效果代码
Mar 12 Javascript
jQuery实现的原图对比窗帘效果
Jun 15 Javascript
js确认删除对话框适用于a标签及submit
Jul 10 Javascript
JavaScript实现in-place思想的快速排序方法
Aug 07 Javascript
在vue中使用css modules替代scroped的方法
Mar 10 Javascript
vue中在vuex的actions中请求数据实例
Nov 08 Javascript
微信小程序动态评分展示/五角星展示/半颗星展示/自定义长度展示功能的实现
Jul 22 Javascript
vuex中遇到的坑,vuex数据改变,组件中页面不渲染操作
Nov 16 Javascript
vue浏览器返回监听的具体步骤
Feb 03 Vue.js
小程序实现侧滑删除功能
Jun 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
php不使用插件导出excel的简单方法
2014/03/04 PHP
Laravel 4.2 中队列服务(queue)使用感受
2014/10/30 PHP
PHP变量赋值、代入给JavaScript中的变量
2015/06/29 PHP
PHP执行普通shell命令流程解析
2020/08/24 PHP
javascript for循环设法提高性能
2010/02/24 Javascript
基于jquery的15款幻灯片插件
2011/04/10 Javascript
jquery 删除字符串最后一个字符的方法解析
2014/02/11 Javascript
js+html5实现可在手机上玩的拼图游戏
2015/07/17 Javascript
js实现全国省份城市级联下拉菜单效果代码
2015/09/07 Javascript
JavaScript实现仿新浪微博大厅和腾讯微博首页滚动特效源码
2015/09/15 Javascript
解决在vue+webpack开发中出现两个或多个菜单公用一个组件问题
2017/11/28 Javascript
npm全局模块卸载及默认安装目录修改方法
2018/05/15 Javascript
react+ant design实现Table的增、删、改的示例代码
2018/12/27 Javascript
基于vue-draggable 实现三级拖动排序效果
2020/01/10 Javascript
jQuery实现轮播图效果demo
2020/01/11 jQuery
Vue设置长时间未操作登录自动到期返回登录页
2020/01/22 Javascript
Vue+Vant 图片上传加显示的案例
2020/11/03 Javascript
python3学习笔记之多进程分布式小例子
2018/02/13 Python
对Python中Iterator和Iterable的区别详解
2018/10/18 Python
Python如何获得百度统计API的数据并发送邮件示例代码
2019/01/27 Python
详解python--模拟轮盘抽奖游戏
2019/04/12 Python
Django Form 实时从数据库中获取数据的操作方法
2019/07/25 Python
使用Tensorflow将自己的数据分割成batch训练实例
2020/01/20 Python
利用Python自动化操作AutoCAD的实现
2020/04/01 Python
吉尔德利巧克力公司:Ghirardelli Chocolate Company
2019/03/27 全球购物
大学生村官工作感言
2014/01/10 职场文书
成考报名单位证明范本
2014/01/16 职场文书
财产公证书样本
2014/04/04 职场文书
优秀的应届生自荐信
2014/05/23 职场文书
国庆节慰问信
2015/02/15 职场文书
六一亲子活动感想
2015/08/07 职场文书
PHP解决高并发问题
2021/04/01 PHP
MySQL下使用Inplace和Online方式创建索引的教程
2021/05/26 MySQL
MySQL系列之十四 MySQL的高可用实现
2021/07/02 MySQL
SpringMVC 整合SSM框架详解
2021/08/30 Java/Android
xhunter1.sys可以删除嘛? win11提示xhunter1.sys驱动不兼容解决办法
2022/09/23 数码科技