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 相关文章推荐
深入理解javascript学习笔记(一) 编写高质量代码
Aug 09 Javascript
JavaScript中number转换成string介绍
Dec 31 Javascript
JS截取字符串实例详解
Nov 24 Javascript
javascript HTML5 Canvas实现圆盘抽奖功能
Apr 11 Javascript
JavaScript中的对象和原型(一)
Aug 12 Javascript
jQuery实现模拟flash头像裁切上传功能示例
Dec 11 Javascript
JS开发中百度地图+城市联动实现实时触发查询地址功能
Apr 13 Javascript
JS实现简易的图片拖拽排序实例代码
Jun 09 Javascript
vue的.vue文件是怎么run起来的(vue-loader)
Dec 10 Javascript
详解Vue.js v-for不支持IE9的解决方法
Dec 29 Javascript
前端插件之Bootstrap Dual Listbox使用教程
Jul 23 Javascript
解决Layui数据表格显示无数据提示的问题
Nov 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
在PHP里得到前天和昨天的日期的代码
2007/08/16 PHP
PHP中nowdoc和heredoc使用需要注意的一点
2014/03/21 PHP
php数据序列化测试实例详解
2017/08/12 PHP
PHP7新特性之抽象语法树(AST)带来的变化详解
2018/07/17 PHP
swoole_process实现进程池的方法示例
2018/10/29 PHP
PHP5.6.8连接SQL Server 2008 R2数据库常用技巧分析总结
2019/05/06 PHP
用jquery来定位
2007/02/20 Javascript
Javascript 文件夹选择框的两种解决方案
2009/07/01 Javascript
jQuery选择头像并实时显示的代码
2010/06/27 Javascript
javascript动态加载实现方法一
2012/08/22 Javascript
jQuery实现图片放大预览实现原理及代码
2013/09/12 Javascript
Javascript弹出窗口的各种方法总结
2013/11/11 Javascript
jQuery 和 CSS 的文本特效插件集锦
2014/12/12 Javascript
基于javascript实现随机颜色变化效果
2016/01/14 Javascript
Js的Array数组对象详解
2016/02/22 Javascript
vue2+el-menu实现路由跳转及当前项的设置方法实例
2017/11/07 Javascript
解决vue 路由变化页面数据不刷新的问题
2018/03/13 Javascript
vue.js实现图书管理功能
2019/09/24 Javascript
JavaScript函数IIFE使用详解
2019/10/21 Javascript
基于JavaScript实现单例模式
2019/10/30 Javascript
vue动态渲染svg、添加点击事件的实现
2020/03/13 Javascript
[08:08]2014DOTA2国际邀请赛中国区预选赛精彩TOPPLAY
2014/06/25 DOTA
python任务调度实例分析
2015/05/19 Python
python如何重载模块实例解析
2018/01/25 Python
浅谈Python traceback的优雅处理
2018/08/31 Python
Python Pandas 如何shuffle(打乱)数据
2019/07/30 Python
Atom Python 配置Python3 解释器的方法
2019/08/28 Python
Python实现打印实心和空心菱形
2019/11/23 Python
Appium+Python实现简单的自动化登录测试的实现
2021/01/26 Python
员工拾金不昧表扬信
2014/01/09 职场文书
无故旷工检讨书
2014/01/26 职场文书
环境工程专业自荐信范文
2014/03/18 职场文书
机关党员三严三实心得体会
2014/10/13 职场文书
大学生心理健康教育心得体会
2016/01/12 职场文书
2016党员干部政治学习心得体会
2016/01/23 职场文书
Go 在 MongoDB 中常用查询与修改的操作
2021/05/07 Golang