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 数组操作代码集锦
Apr 28 Javascript
JS定义回车事件(实现代码)
Jul 08 Javascript
js实现模拟计算器退格键删除文字效果的方法
May 07 Javascript
JavaScript入门基础
Aug 12 Javascript
footer定位页面底部(代码分享)
Mar 07 Javascript
原生javascript实现分页效果
Apr 21 Javascript
微信小程序模板(template)使用详解
Jan 31 Javascript
Vue模拟数据,实现路由进入商品详情页面的示例
Aug 31 Javascript
jQuery超简单遮罩层实现方法示例
Sep 06 jQuery
详解ES6 CLASS在微信小程序中的应用实例
Apr 24 Javascript
vue tab切换,解决echartst图表宽度只有100px的问题
Jul 19 Javascript
解决vue-loader加载不上的问题
Oct 21 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
【星际争霸1】人族1v7家ZBath
2020/03/04 星际争霸
PHP 编程请选择正确的文本编辑软件
2006/12/21 PHP
PHP 使用MySQL管理Session的回调函数详解
2013/06/21 PHP
php简单操作mysql数据库的类
2015/04/16 PHP
Yii CDBCriteria常用方法实例小结
2017/01/19 PHP
Laravel实现ApiToken认证请求
2019/10/14 PHP
jQuery技巧大放送 学习jquery的朋友可以看下
2009/10/14 Javascript
JS父页面与子页面相互传值方法
2014/03/05 Javascript
js简单实现交换Li的值
2014/05/22 Javascript
sogou地图API用法实例教程
2014/09/11 Javascript
ECMA5数组的新增方法有哪些及forEach()模仿实现
2015/11/03 Javascript
深入理解JavaScript中的浮点数
2016/05/18 Javascript
浅谈JavaScript中数组的增删改查
2016/06/20 Javascript
js微信分享API
2020/10/11 Javascript
使用nodejs爬取前程无忧前端技能排行
2017/05/06 NodeJs
利用node.js如何创建子进程详解
2017/12/09 Javascript
JS设计模式之命令模式概念与用法分析
2018/02/06 Javascript
jquery点击回车键实现登录效果并默认焦点的方法
2018/03/09 jQuery
element-ui 上传图片后清空图片显示的实例
2018/09/04 Javascript
微信小程序五子棋游戏AI实现方法【附demo源码下载】
2019/02/20 Javascript
bootstrap table.js动态填充单元格数据的多种方法
2019/07/18 Javascript
vue项目中常见问题及解决方案(推荐)
2019/10/21 Javascript
[35:34]Liquid vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Ubuntu 下 vim 搭建python 环境 配置
2017/06/12 Python
解决python3捕获cx_oracle抛出的异常错误问题
2018/10/18 Python
使用python采集脚本之家电子书资源并自动下载到本地的实例脚本
2018/10/23 Python
Python函数基础实例详解【函数嵌套,命名空间,函数对象,闭包函数等】
2019/03/30 Python
python读取raw binary图片并提取统计信息的实例
2020/01/09 Python
python和C++共享内存传输图像的示例
2020/10/27 Python
手把手教你从PyCharm安装到激活(最新激活码),亲测有效可激活至2089年
2020/11/25 Python
详解html2canvas截图不能截取圆角图片的解决方案
2018/01/30 HTML / CSS
庆元旦迎新年广播稿
2014/02/18 职场文书
消防安全承诺书
2014/05/22 职场文书
图书馆志愿者活动总结
2014/06/27 职场文书
“四风”问题对照检查材料思想汇报
2014/09/16 职场文书
员工2014年度工作总结
2014/12/09 职场文书