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 相关文章推荐
textarea 控制输入字符字节数(示例代码)
Dec 27 Javascript
jQuery应用之jQuery链用法实例
Jan 19 Javascript
PHP中CURL的几个经典应用实例
Jan 23 Javascript
JS简单实现城市二级联动选择插件的方法
Aug 19 Javascript
JS实现的新浪微博大厅文字内容滚动效果代码
Nov 05 Javascript
javascript基本常用排序算法解析
Sep 27 Javascript
详解Vue-cli中的静态资源管理(src/assets和static/的区别)
Jun 19 Javascript
ES6中的class是如何实现的(附Babel编译的ES5代码详解)
May 17 Javascript
JS实现简单的文字无缝上下滚动功能示例
Jun 22 Javascript
Electron 调用命令行(cmd)
Sep 23 Javascript
Vue.js组件props数据验证实现详解
Oct 19 Javascript
关于Javascript闭包与应用的详解
Apr 22 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在XP下IIS和Apache2服务器上的安装
2006/09/05 PHP
ecshop 订单确认中显示省市地址信息的方法
2010/03/15 PHP
PHP 魔术函数使用说明
2010/05/14 PHP
PHP字符串的递增和递减示例介绍
2014/02/11 PHP
PHP获取mysql数据表的字段名称和详细信息的方法
2014/09/27 PHP
PHP统计数值数组中出现频率最多的10个数字的方法
2015/04/20 PHP
对于Laravel 5.5核心架构的深入理解
2018/02/22 PHP
Jquery 一次处理多个ajax请求的代码
2011/09/02 Javascript
jquery上传插件fineuploader上传文件使用方法(jquery图片上传插件)
2013/12/05 Javascript
jquery果冻抖动效果实现方法
2015/01/15 Javascript
JS实现表单中checkbox对勾选中增加边框显示效果
2015/08/21 Javascript
node.js入门实例helloworld详解
2015/12/23 Javascript
快速使用Bootstrap搭建传送带
2016/05/06 Javascript
浅析jQuery 3.0中的Data
2016/06/14 Javascript
分享jQuery封装好的一些常用操作
2016/07/28 Javascript
微信小程序 视图层(xx.xml)和逻辑层(xx.js)详细介绍
2016/10/13 Javascript
Angular学习笔记之angular的$filter服务浅析
2016/11/12 Javascript
ES6中的rest参数与扩展运算符详解
2017/07/18 Javascript
深入浅出webpack之externals的使用
2017/12/04 Javascript
vue自定义全局组件(自定义插件)的用法
2018/01/30 Javascript
vue项目打包上传github并制作预览链接(pages)
2019/04/19 Javascript
vue实现网络图片瀑布流 + 下拉刷新 + 上拉加载更多(步骤详解)
2020/01/14 Javascript
javascript将16进制的字符串转换为10进制整数hex
2020/03/05 Javascript
详细分析React 表单与事件
2020/07/08 Javascript
npm ci命令的基本使用方法
2020/09/20 Javascript
NestJs使用Mongoose对MongoDB操作的方法
2021/02/22 Javascript
[05:04]完美世界携手游戏风云打造 卡尔工作室地图界面篇
2013/04/23 DOTA
Pyhton中防止SQL注入的方法
2015/02/05 Python
python爬取网页转换为PDF文件
2018/06/07 Python
flask框架url与重定向操作实例详解
2020/01/25 Python
Python之京东商品秒杀的实现示例
2021/01/06 Python
创伤外科专业推荐信范文
2013/11/19 职场文书
秋季婚礼证婚词
2014/01/11 职场文书
咖啡馆创业计划书
2014/01/26 职场文书
2014年纪检部工作总结
2014/11/12 职场文书
民事上诉状范文
2015/05/22 职场文书