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 相关文章推荐
jQuery.buildFragment使用方法及思路分析
Jan 07 Javascript
图片上传判断及预览脚本的效果实例
Aug 07 Javascript
JS对象与json字符串格式转换实例
Oct 28 Javascript
Jquery插件实现点击获取验证码后60秒内禁止重新获取
Mar 13 Javascript
学习JavaScript编程语言的8张思维导图分享
Mar 27 Javascript
JQuery实现简单的图片滑动切换特效
Nov 22 Javascript
js获取url传值的方法
Dec 18 Javascript
jquery过滤特殊字符',防sql注入的实现方法
Aug 17 Javascript
Javascript使用SWFUpload进行多文件上传
Nov 16 Javascript
ES6新特性之解构、参数、模块和记号用法示例
Apr 01 Javascript
详解Vue底部导航栏组件
May 02 Javascript
typescript编写微信小程序创建项目的方法
Jan 29 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
php selectradio和checkbox默认选择的实现方法详解
2013/06/29 PHP
PHP return语句另类用法不止是在函数中
2014/09/17 PHP
PHP中include和require的区别实例分析
2017/05/07 PHP
TP(thinkPHP)框架多层控制器和多级控制器的使用示例
2018/06/13 PHP
不能再简单的无闪刷新验证码原理很简单
2007/11/05 Javascript
javascript 函数参数限制说明
2010/11/19 Javascript
js获取select标签的值且兼容IE与firefox
2013/12/30 Javascript
文本框文本自动补全效果示例分享
2014/01/19 Javascript
jquery序列化form表单使用ajax提交后处理返回的json数据
2014/03/03 Javascript
node.js解决获取图片真实文件类型的问题
2014/12/20 Javascript
JavaScript图片轮播代码分享
2015/07/31 Javascript
基于Jquery实现焦点图淡出淡入效果
2015/11/30 Javascript
jQuery数据类型小结(14个)
2016/01/08 Javascript
jquery对象和DOM对象的任意相互转换
2016/02/21 Javascript
JSON 的正确用法探讨:Pyhong、MongoDB、JavaScript与Ajax
2016/05/15 Javascript
ES6新特性之字符串的扩展实例分析
2017/04/01 Javascript
一个简易的js图片轮播效果
2017/07/22 Javascript
Angular4如何自定义首屏的加载动画详解
2017/07/26 Javascript
vue-cli2.x项目优化之引入本地静态库文件的方法
2018/06/19 Javascript
LayUI表格批量删除方法
2018/08/15 Javascript
用Cordova打包Vue项目的方法步骤
2019/02/02 Javascript
Nodejs中怎么实现函数的串行执行
2019/03/02 NodeJs
vant-ui组件调用Dialog弹窗异步关闭操作
2020/11/04 Javascript
[01:02:03]2014 DOTA2华西杯精英邀请赛 5 24 NewBee VS VG
2014/05/26 DOTA
让python json encode datetime类型
2010/12/28 Python
python为tornado添加recaptcha验证码功能
2014/02/26 Python
在Python中使用PIL模块处理图像的教程
2015/04/29 Python
Python类的动态修改的实例方法
2017/03/24 Python
Django contenttypes 框架详解(小结)
2018/08/13 Python
python实现字符串完美拆分split()的方法
2019/07/16 Python
Python 3 判断2个字典相同
2019/08/06 Python
python使用celery实现异步任务执行的例子
2019/08/28 Python
Python3读写Excel文件(使用xlrd,xlsxwriter,openpyxl3种方式读写实例与优劣)
2020/02/13 Python
Pytorch .pth权重文件的使用解析
2020/02/14 Python
简单的离婚协议书范本
2014/11/16 职场文书
2016大学生社会实践单位评语
2015/12/01 职场文书