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语法对{}处理的坑爹之处
Jun 05 Javascript
使用jQuery实现验证上传图片的格式与大小
Dec 03 Javascript
JS类的定义与使用方法深入探索
Nov 26 Javascript
基于BootStrap栅格栏系统完成网站底部版权信息区
Dec 23 Javascript
JavaScript正则表达式替换字符串中图片地址(img src)的方法
Jan 13 Javascript
js实现动态显示时间效果
Mar 06 Javascript
JS库之Highlight.js的用法详解
Sep 13 Javascript
AngularJS中scope的绑定策略实例分析
Oct 30 Javascript
React SSR样式及SEO的实践
Oct 22 Javascript
vue生命周期的探索
Apr 03 Javascript
微信小程序组件传值图示过程详解
Jul 31 Javascript
浅析vue中的nextTick
Dec 28 Vue.js
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
星际争霸秘籍
2020/03/04 星际争霸
mysq GBKl乱码
2006/11/28 PHP
有关 PHP 和 MySQL 时区的一点总结
2008/03/26 PHP
PHP正则表达式入门教程(推荐)
2016/05/18 PHP
解决FireFox下[使用event很麻烦]的问题
2006/11/26 Javascript
jQuery Tips 为AJAX回调函数传递额外参数的方法
2010/12/28 Javascript
jquery控制select的text/value值为选中状态
2014/06/03 Javascript
深入理解js数组的sort排序
2016/05/28 Javascript
Bootstrap3 模态框使用实例
2017/02/22 Javascript
VueJS 集成 Medium Editor的示例代码 (自定义编辑器按钮)
2017/08/24 Javascript
jquery点击回车键实现登录效果并默认焦点的方法
2018/03/09 jQuery
[原创]jquery判断元素内容是否为空的方法
2018/05/04 jQuery
详解使用jQuery.i18n.properties实现js国际化
2018/05/04 jQuery
js根据需要计算数组中重复出现某个元素的个数
2019/01/18 Javascript
vscode vue 文件模板的配置方法
2019/07/23 Javascript
在antd4.0中Form使用initialValue操作
2020/11/02 Javascript
Vue使用Element实现增删改查+打包的步骤
2020/11/25 Vue.js
python元组操作实例解析
2014/09/23 Python
Python 私有函数的实例详解
2017/09/11 Python
python中scikit-learn机器代码实例
2018/08/05 Python
详解Python静态网页爬取获取高清壁纸
2019/04/23 Python
将Pytorch模型从CPU转换成GPU的实现方法
2019/08/19 Python
python matplotlib:plt.scatter() 大小和颜色参数详解
2020/04/14 Python
python 异步async库的使用说明
2020/05/04 Python
scrapy与selenium结合爬取数据(爬取动态网站)的示例代码
2020/09/28 Python
python实现企业微信定时发送文本消息的实例代码
2020/11/25 Python
Waterford加拿大官方网站:世界著名的水晶杯品牌
2016/11/01 全球购物
香奈儿美国官网:CHANEL美国
2020/05/20 全球购物
超市开店计划书
2014/04/26 职场文书
党组织领导班子整改方案
2014/10/25 职场文书
党的群众路线教育实践活动个人整改措施范文
2014/11/04 职场文书
小学生心理健康活动总结
2015/05/08 职场文书
小学生六年级作文之关于感恩
2019/08/16 职场文书
2019新员工试用期转正工作总结范文
2019/08/21 职场文书
创业计划书之熟食店
2019/10/16 职场文书
django学习之ajax post传参的2种格式实例
2021/05/14 Python