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工具 Cookie 封装
Aug 21 Javascript
js导出txt示例代码
Jan 14 Javascript
Jquery选择器中使用变量实现动态选择例子
Jul 25 Javascript
什么是 AngularJS?AngularJS简介
Dec 06 Javascript
用队列模拟jquery的动画算法实例
Jan 20 Javascript
javascript中数组方法汇总
Jul 07 Javascript
js实现3D图片逐张轮播幻灯片特效代码分享
Sep 09 Javascript
jquery ajax分页插件的简单实现
Jan 27 Javascript
jQuery弹出层后禁用底部滚动条(移动端关闭回到原位置)
Aug 29 Javascript
JS实现获取毫秒值及转换成年月日时分秒的方法
Aug 15 Javascript
vue实现页面滚动到底部刷新
Aug 16 Javascript
用javascript制作qq注册动态页面
Apr 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
Smarty Foreach 使用说明
2010/03/23 PHP
php实现倒计时效果
2015/12/19 PHP
Linux下快速搭建php开发环境
2017/03/13 PHP
Nigma vs AM BO3 第一场2.13
2021/03/10 DOTA
jquery live()调用不存在的解决方法
2014/02/26 Javascript
JavaScript类继承及实例化的方法
2015/07/25 Javascript
详解javascript中的事件处理
2015/11/06 Javascript
AngularJS 过滤器的简单实例
2016/07/27 Javascript
js字符串引用的两种方式(必看)
2016/09/18 Javascript
微信小程序 限制1M的瘦身技巧与方法详解
2017/01/06 Javascript
node学习记录之搭建web服务器教程
2017/02/16 Javascript
jQuery鼠标移动图片上实现放大效果
2017/06/25 jQuery
使用JavaScript根据图片获取条形码的方法
2017/07/04 Javascript
JS实现发送短信验证后按钮倒计时功能(防止刷新倒计时失效)
2017/07/07 Javascript
解决vue router组件状态刷新消失的问题
2018/08/01 Javascript
通过实例了解Render Props回调地狱解决方案
2020/11/04 Javascript
使用Python的Django框架实现事务交易管理的教程
2015/04/20 Python
python3实现暴力穷举博客园密码
2016/06/19 Python
详解Python各大聊天系统的屏蔽脏话功能原理
2016/12/01 Python
浅谈Python浅拷贝、深拷贝及引用机制
2016/12/15 Python
python如何去除字符串中不想要的字符
2020/07/05 Python
Python视频爬虫实现下载头条视频功能示例
2018/05/07 Python
Python文件监听工具pyinotify与watchdog实例
2018/10/15 Python
python 去除二维数组/二维列表中的重复行方法
2019/01/23 Python
Python3使用Matplotlib 绘制精美的数学函数图形
2019/04/11 Python
详解Python连接MySQL数据库的多种方式
2019/04/16 Python
Pycharm中配置远程Docker运行环境的教程图解
2020/06/11 Python
Django def clean()函数对表单中的数据进行验证操作
2020/07/09 Python
谈谈python垃圾回收机制
2020/09/27 Python
车间副主任岗位职责
2013/12/24 职场文书
护理专业优质毕业生自荐书
2014/01/31 职场文书
竞选卫生委员演讲稿
2014/04/28 职场文书
焦裕禄精神心得体会
2014/09/02 职场文书
学校中秋节活动总结
2015/03/23 职场文书
MySQL RC事务隔离的实现
2022/03/31 MySQL
golang三种设计模式之简单工厂、方法工厂和抽象工厂
2022/04/10 Golang