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 相关文章推荐
jquery实现页面图片等比例放大缩小功能
Feb 12 Javascript
关于事件mouseover ,mouseout ,mouseenter,mouseleave的区别
Oct 12 Javascript
实例代码详解jquery.slides.js
Nov 16 Javascript
实例讲解jquery与json的结合
Jan 07 Javascript
如何检测JavaScript的各种类型
Jul 30 Javascript
Js查找字符串中出现次数最多的字符及个数实例解析
Sep 05 Javascript
微信小程序 wx.request(接口调用方式)详解及实例
Nov 23 Javascript
JQuery form表单提交前验证单选框是否选中、删除记录时验证经验总结(整理)
Jun 09 jQuery
vue-resource调用promise取数据方式详解
Jul 21 Javascript
通过js动态创建标签,并设置属性方法
Feb 24 Javascript
vue页面更新patch的实现示例
Mar 25 Javascript
vue 解决setTimeOut和setInterval函数无效报错的问题
Jul 30 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
Yii框架获取当前controlle和action对应id的方法
2014/12/03 PHP
ajax+php实现无刷新验证手机号的实例
2017/12/22 PHP
PHP的mysqli_stmt_init()函数讲解
2019/01/24 PHP
关于laravel 子查询 &amp; join的使用
2019/10/16 PHP
Javascript 复制数组实现代码
2009/11/26 Javascript
javascript中运用闭包和自执行函数解决大量的全局变量问题
2010/12/30 Javascript
事件冒泡是什么如何用jquery阻止事件冒泡
2013/03/20 Javascript
通过JQuery实现win8一样酷炫的动态磁贴效果(示例代码)
2013/07/13 Javascript
JavaScript字符串删除重复字符的方法
2015/12/25 Javascript
JS实现图片平面旋转的方法
2016/03/01 Javascript
Three.js学习之网格
2016/08/10 Javascript
AngularJS中如何使用echart插件示例详解
2016/10/26 Javascript
Angular2学习笔记——详解路由器模型(Router)
2016/12/02 Javascript
Bootstrap滚动监听组件scrollspy.js使用方法详解
2017/07/20 Javascript
react-router4 配合webpack require.ensure 实现异步加载的示例
2018/01/18 Javascript
微信小程序实现左右列表联动
2020/05/19 Javascript
bootstrap table.js动态填充单元格数据的多种方法
2019/07/18 Javascript
微信小程序文字显示换行问题
2019/07/28 Javascript
layui prompt 设置允许空白提交的方法
2019/09/24 Javascript
vue-router 2.0 跳转之router.push()用法说明
2020/08/12 Javascript
解决windows下Sublime Text 2 运行 PyQt 不显示的方法分享
2014/06/18 Python
python实现图片筛选程序
2018/10/24 Python
对python当中不在本路径的py文件的引用详解
2018/12/15 Python
python基础梳理(一)(推荐)
2019/04/06 Python
详解canvas绘制网络字体几种方法
2019/08/27 HTML / CSS
荷兰网上买鞋:MooieSchoenen.nl
2017/09/12 全球购物
英国家喻户晓的高街品牌:River Island
2017/11/28 全球购物
大学英语演讲稿范文
2014/04/24 职场文书
购房个人委托书范本
2014/10/11 职场文书
个人务虚会发言材料
2014/10/20 职场文书
2015关爱留守儿童工作总结
2014/12/12 职场文书
工程服务质量承诺书
2015/04/29 职场文书
2016重阳节红领巾广播稿
2015/12/18 职场文书
《穷人》教学反思
2016/02/19 职场文书
python基础之停用词过滤详解
2021/04/21 Python
浅谈Redis跟MySQL的双写问题解决方案
2022/02/24 Redis