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模拟类继承小例子
Jul 17 Javascript
JavaScript自动设置IFrame高度的小例子
Jun 08 Javascript
setTimeout()与setInterval()方法区别介绍
Dec 24 Javascript
JavaScript中统计Textarea字数并提示还能输入的字符
Jun 10 Javascript
javascript实现iframe框架延时加载的方法
Oct 30 Javascript
js微信分享API
Oct 11 Javascript
AngularJS基础 ng-copy 指令实例代码
Aug 01 Javascript
js eval函数使用,js对象和字符串互转实例
Mar 06 Javascript
微信小程序页面滑动屏幕加载数据效果
Nov 16 Javascript
AngularJS实现自定义指令及指令配置项的方法
Nov 20 Javascript
Vue实现类似Spring官网图片滑动效果方法
Mar 01 Javascript
详解element-ui级联菜单(城市三级联动菜单)和回显问题
Oct 02 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
完美解决dedecms中的[html][/html]和[code][/code]问题
2007/03/20 PHP
PHP 字符串编码截取函数(兼容utf-8和gb2312)
2009/05/02 PHP
PHP扩展开发入门教程
2015/02/26 PHP
php文件上传你必须知道的几点
2015/10/20 PHP
How to Auto Include a Javascript File
2007/02/02 Javascript
Jquery 插件学习实例1 插件制作说明与tableUI优化
2010/04/02 Javascript
读JavaScript DOM编程艺术笔记
2011/11/15 Javascript
JavaScript中valueOf函数与toString方法深入理解
2012/12/02 Javascript
Jquery+asp.net后台数据传到前台js进行解析的方法
2014/05/11 Javascript
js与jQuery实现checkbox复选框全选/全不选的方法
2016/01/05 Javascript
JS函数定义方式的区别介绍
2016/03/22 Javascript
JavaScript闭包和范围实例详解
2016/12/19 Javascript
jQuery实现简单的滑动导航代码(移动端)
2017/05/22 jQuery
angular实现图片懒加载实例代码
2017/06/08 Javascript
详解vue中axios请求的封装
2019/04/08 Javascript
Javascript var变量删除原理及实现
2020/08/26 Javascript
通过实例解析jQ Ajax操作相关原理
2020/09/23 Javascript
vue解决跨域问题(推荐)
2020/11/10 Javascript
一篇文章看懂JavaScript中的回调
2021/01/05 Javascript
python通过urllib2获取带有中文参数url内容的方法
2015/03/13 Python
举例讲解Python中的算数运算符的用法
2015/05/13 Python
Python使用PIL库实现验证码图片的方法
2016/03/11 Python
使用opencv将视频帧转成图片输出
2019/12/10 Python
pytorch实现特殊的Module--Sqeuential三种写法
2020/01/15 Python
pycharm 配置svn的图文教程(手把手教你)
2021/01/15 Python
python FTP编程基础入门
2021/02/27 Python
ziaja齐叶雅官方海外旗舰店:来自波兰的天然护肤品牌
2017/01/02 全球购物
是否可以从一个static方法内部发出对非static方法的调用?
2014/08/18 面试题
军训心得体会
2013/12/31 职场文书
教师节商场活动方案
2014/02/13 职场文书
献爱心活动总结
2014/05/07 职场文书
节约用水演讲稿
2014/05/21 职场文书
自查自纠工作情况报告
2014/10/29 职场文书
交通事故被告代理词
2015/05/23 职场文书
redis protocol通信协议及使用详解
2022/07/15 Redis
HTML页面点击按钮关闭页面的多种方式
2022/12/24 HTML / CSS