vue自定义指令之面板拖拽的实现


Posted in Javascript onApril 14, 2019

前言

在指令里获取的this并不是vue对象,vnode.context才是vue对象,一般来说,指令最好不要访问vue上的data,以追求解耦,但是可以通过指令传进来的值去访问method或ref之类的。

vue指令

官方文档其实已经解释的蛮清楚了,这里挑几个重点的来讲。

1、arguments

el: 当前的node对象,用于操作dom
binding:模版解析之后的值
vNode: Vue 编译生成的虚拟节点,可以在上面获取vue对象
oldVnode: 使用当前指令上一次变化的node内容

2、 生命周期

bind: 初始化的时候调用,但这时候node不一定渲染完成
inserted: 被绑定元素插入父节点时调用,关于dom操作尽量在这里用
update:就是内部this.update时会触发这里

面板拖拽逻辑

使用relative,舰艇event上的clientX和clientY鼠标距离页面的位置来改变面板的top和left。

涉及属性

  • offsetLeft:距离参照元素左边界偏移量
  • offsetTop:距离参照元素上边界偏移量
  • clientWidth:此属性可以返回指定元素客户区宽度
  • clientHeight: 此属性可以返回指定元素客户区高度
  • clientX:事件被触发时鼠标指针相对于浏览器页面(或客户区)的水平坐标
  • clientY: 事件被触发时鼠标指针相对于浏览器页面(或客户区)的垂直坐标
  • onmousedown:鼠标按下事件
  • onmousemove: 鼠标滑动事件
  • onmouseup: 鼠标松开事件

实现代码

<div v-drag="'refName'"></div>

在绑定的组件上使用,value非必选项,不挑就默认是基于document的移动

directives: {
  drag: {
   // 使用bind会有可能没有渲染完成
   inserted: function(el, binding, vnode) {
    const _el = el; //获取当前元素
    const ref = vnode.context.$refs[binding.value]; // 判断基于移动的是哪一个盒子
    const masterNode = ref ? ref : document; // 用于绑定事件
    const masterBody = ref ? ref : document.body; // 用于获取高和宽
    const mgl = _el.offsetLeft;
    const mgt = _el.offsetTop;
    const maxWidth = masterBody.clientWidth;
    const maxHeight = masterBody.clientHeight;
    const elWidth = _el.clientWidth;
    const elHeight = _el.clientHeight;
    let positionX = 0,
     positionY = 0;
    _el.onmousedown = e => {
     //算出鼠标相对元素的位置,加上的值是margin的值
     let disX = e.clientX - _el.offsetLeft + mgl; 
     let disY = e.clientY - _el.offsetTop + mgt;
     masterNode.onmousemove = e => {
      //用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
      let left = e.clientX - disX;
      let top = e.clientY - disY;
      // 绑定的值不能滑出基于盒子的范围
      left < 0 && (left = 0);
      left > (maxWidth - elWidth - mgl) && (left = maxWidth - elWidth - mgl);
      top < 0 && (top = 0);
      top > (maxHeight - elHeight - mgt) && (top = maxHeight - elHeight - mgt);
      //绑定元素位置到positionX和positionY上面
      positionX = top;
      positionY = left;
      
      //移动当前元素
      _el.style.left = left + "px";
      _el.style.top = top + "px";
     };
     // 这里是鼠标超出基于盒子范围之后再松开,会监听不到
     document.onmouseup = e => {
      masterNode.onmousemove = null;
      document.onmouseup = null;
     };
    };
   }
  }
 }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js获取UserControl内容为拼html时提供方便
Nov 02 Javascript
深入理解JavaScript系列(28):设计模式之工厂模式详解
Mar 03 Javascript
基于Jquery+div+css实现弹出登录窗口(代码超简单)
Oct 27 Javascript
AngularJs Javascript MVC 框架
Jun 20 Javascript
用headjs来管理和加载js 提高网站加载速度
Nov 29 Javascript
Bootstrap基本组件学习笔记之按钮组(8)
Dec 07 Javascript
动态统计当前输入内容的字节、字符数的实例详解
Oct 27 Javascript
详解如何使用PM2将Node.js的集群变得更加容易
Nov 15 Javascript
Node错误处理笔记之挖坑系列教程
Jun 05 Javascript
Vue.js实现可排序的表格组件功能示例
Feb 19 Javascript
vue实现简单图片上传
Jun 30 Javascript
JS前端可扩展的低代码UI框架Sunmao使用详解
Jul 23 Javascript
详解Vue组件之间通信的七种方式
Apr 14 #Javascript
浅谈Vue CLI 3结合Lerna进行UI框架设计
Apr 14 #Javascript
vue使用axios上传文件(FormData)的方法
Apr 14 #Javascript
详解如何理解vue的key属性
Apr 14 #Javascript
axios+Vue实现上传文件显示进度功能
Apr 14 #Javascript
Vue 使用formData方式向后台发送数据的实现
Apr 14 #Javascript
说说如何使用Vuex进行状态管理(小结)
Apr 14 #Javascript
You might like
海河写的 Discuz论坛帖子调用js的php代码
2007/08/23 PHP
选择PHP作为网站开发语言的原因分享
2012/01/03 PHP
Linux下实现PHP多进程的方法分享
2012/08/16 PHP
Thinkphp实现MySQL读写分离操作示例
2014/06/25 PHP
Microsoft Ajax Minifier 压缩javascript的方法
2010/03/05 Javascript
jQuery实现的类flash菜单效果代码
2010/05/17 Javascript
jQuery之排序组件的深入解析
2013/06/19 Javascript
JavaScript使用slice函数获取数组部分元素的方法
2015/04/06 Javascript
JavaScript实现控制打开文件另存为对话框的方法
2015/04/17 Javascript
jQuery获取attr()与prop()属性值的方法及区别介绍
2016/07/06 Javascript
vuejs绑定class和style样式
2017/04/11 Javascript
JavaScript之json_动力节点Java学院整理
2017/06/29 Javascript
vue2中的keep-alive使用总结及注意事项
2017/12/21 Javascript
Vue-cropper 图片裁剪的基本原理及思路讲解
2018/04/17 Javascript
vue图片加载失败时用默认图片替换的方法
2019/08/29 Javascript
createObjectURL方法实现本地图片预览
2019/09/30 Javascript
微信小程序实现注册登录功能(表单校验、错误提示)
2019/12/10 Javascript
Vue实现简单计算器案例
2020/02/25 Javascript
jQuery+Ajax+js实现请求json格式数据并渲染到html页面操作示例
2020/06/02 jQuery
Python如何快速实现分布式任务
2017/07/06 Python
Python轻量级ORM框架Peewee访问sqlite数据库的方法详解
2017/07/20 Python
浅谈python装饰器探究与参数的领取
2017/12/01 Python
Python中%是什么意思?python中百分号如何使用?
2018/03/20 Python
Atom的python插件和常用插件说明
2018/07/08 Python
浅谈pandas用groupby后对层级索引levels的处理方法
2018/11/06 Python
对python中的six.moves模块的下载函数urlretrieve详解
2018/12/19 Python
Python父目录、子目录的相互调用方法
2019/02/16 Python
Python的numpy库下的几个小函数的用法(小结)
2019/07/12 Python
Python 中list ,set,dict的大规模查找效率对比详解
2019/10/11 Python
HTML高亮关键字的实现代码
2018/10/22 HTML / CSS
标记环介质访问控制协议
2016/03/27 面试题
咨询公司各岗位职责
2013/12/02 职场文书
2014年保密工作总结
2014/11/22 职场文书
教师培训简讯
2015/07/20 职场文书
详解Spring Boot使用系统参数表提升系统的灵活性
2021/06/30 Java/Android
golang三种设计模式之简单工厂、方法工厂和抽象工厂
2022/04/10 Golang