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 相关文章推荐
你需要知道的10个最佳javascript开发实践小结
Apr 15 Javascript
JS动态添加option和删除option(附实例代码)
Apr 01 Javascript
Jquery获取和修改img的src值的方法
Feb 17 Javascript
强大Vue.js组件浅析
Sep 12 Javascript
基于JavaScript实现的插入排序算法分析
Apr 14 Javascript
简单谈谈React中的路由系统
Jul 25 Javascript
jQuery创建及操作xml格式数据示例
May 26 jQuery
详解vue文件中使用echarts.js的两种方式
Oct 18 Javascript
JavaScript&quot;模拟事件&quot;的注意要点详解
Feb 13 Javascript
vue在路由中验证token是否存在的简单实现
Nov 11 Javascript
Nuxt默认模板、默认布局和自定义错误页面的实现
May 11 Javascript
使用javascript解析二维码的三种方式
Nov 11 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
ThinkPHP上使用多说评论插件的方法
2014/10/31 PHP
浅谈php+phpStorm+xdebug配置方法
2015/09/17 PHP
thinkPHP内置字符串截取函数用法详解
2016/11/15 PHP
php实现多站点共用session实现单点登录的方法详解
2019/09/18 PHP
asp.net下利用js实现返回上一页的实现方法小集
2009/11/24 Javascript
cookie.js 加载顺序问题怎么才有效
2013/07/31 Javascript
jQuery中html()方法用法实例
2014/12/25 Javascript
JavaScript中的标签语句用法分析
2015/02/10 Javascript
javascript等号运算符使用详解
2015/04/16 Javascript
JavaScript实现仿网易通行证表单验证
2015/05/25 Javascript
js代码实现随机颜色的小方块
2015/07/30 Javascript
JS中的forEach、$.each、map方法推荐
2016/04/05 Javascript
JavaScript事件详细讲解
2016/06/27 Javascript
浅谈Angular的$q, defer, promise
2016/12/20 Javascript
Vue.js常用指令之循环使用v-for指令教程
2017/06/27 Javascript
vue绑定class与行间样式style详解
2017/08/16 Javascript
详解VUE 对element-ui中的ElTableColumn扩展
2018/03/28 Javascript
Vue中关闭弹窗组件时销毁并隐藏操作
2020/09/01 Javascript
Vue中nprogress页面加载进度条的方法实现
2020/11/13 Javascript
ES6学习教程之Promise用法详解
2020/11/22 Javascript
[01:11:08]Winstrike vs NB 2018国际邀请赛淘汰赛BO1 8.21
2018/08/22 DOTA
python使用urllib模块和pyquery实现阿里巴巴排名查询
2014/01/16 Python
Python中运行并行任务技巧
2015/02/26 Python
Python3连接SQLServer、Oracle、MySql的方法
2018/06/28 Python
python实现翻转棋游戏(othello)
2019/07/29 Python
ORM Django 终端打印 SQL 语句实现解析
2019/08/09 Python
python中pandas库中DataFrame对行和列的操作使用方法示例
2020/06/14 Python
戴森西班牙官网:Dyson西班牙
2020/02/04 全球购物
就业推荐表自我鉴定
2013/10/29 职场文书
颂军魂爱军营演讲稿
2014/09/13 职场文书
公安机关党的群众路线教育实践活动剖析材料
2014/10/10 职场文书
党员个人整改措施
2014/10/24 职场文书
研究生给导师的自荐信
2015/03/06 职场文书
药品销售员2015年终工作总结
2015/10/22 职场文书
Redis集群的关闭与重启操作
2021/07/07 Redis
Spring Boot优化后启动速度快到飞起技巧示例
2022/07/23 Java/Android