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 相关文章推荐
javascript强制点击广告的方法
Feb 06 Javascript
javascript实现动态统计图开发实例
Nov 21 Javascript
详解Vue生命周期的示例
Mar 10 Javascript
基于BootStrap multiselect.js实现的下拉框联动效果
Jul 28 Javascript
JavaScript使用FileReader实现图片上传预览效果
Mar 27 Javascript
AngularJS中table表格基本操作示例
Oct 10 Javascript
小程序实现单选多选功能
Nov 04 Javascript
js+HTML5 canvas 实现简单的加载条(进度条)功能示例
Jul 16 Javascript
vue 实现模糊检索并根据其他字符的首字母顺序排列
Sep 19 Javascript
js代码实现轮播图
May 04 Javascript
解决antd Form 表单校验方法无响应的问题
Oct 27 Javascript
详解如何解决使用JSON.stringify时遇到的循环引用问题
Mar 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
杏林同学录(八)
2006/10/09 PHP
Wordpress 相册插件 NextGEN-Gallery 添加目录将中文转为拼音的解决办法
2010/12/29 PHP
无刷新动态加载数据 滚动条加载适合评论等页面
2013/10/16 PHP
Javascript学习笔记 delete运算符
2011/09/13 Javascript
Javascript Request获取请求参数如何实现
2012/11/28 Javascript
jQuery 网易相册鼠标移动显示隐藏效果实现代码
2013/03/31 Javascript
JavaScript自定义日期格式化函数详细解析
2014/01/14 Javascript
javascript替换已有元素replaceChild()使用介绍
2014/04/03 Javascript
jquery任意位置浮动固定层插件用法实例
2015/05/29 Javascript
Angular.js与Bootstrap相结合实现手风琴菜单代码
2016/04/13 Javascript
HTML中setCapture、releaseCapture 使用方法浅析
2016/09/25 Javascript
Highcharts+NodeJS搭建数据可视化平台示例
2017/01/01 NodeJs
JS中传递参数的几种不同方法比较
2017/01/20 Javascript
借助node实战JSONP跨域实例
2017/03/30 Javascript
JS实现的Object数组去重功能示例【数组成员为Object对象】
2019/02/01 Javascript
微信小程序学习笔记之本地数据缓存功能详解
2019/03/29 Javascript
vue canvas绘制矩形并解决由clearRec带来的闪屏问题
2019/09/02 Javascript
[04:26]DOTA2上海特锦赛小组赛第二日 TOP10精彩集锦
2016/02/27 DOTA
[02:00]最后,我终于出了辉耀
2018/03/27 DOTA
[00:15]TI9观赛名额抽取
2019/07/10 DOTA
Python中实现的RC4算法
2015/02/14 Python
Mac中升级Python2.7到Python3.5步骤详解
2017/04/27 Python
实用自动化运维Python脚本分享
2018/06/04 Python
解决django后台样式丢失,css资源加载失败的问题
2019/06/11 Python
pandas如何处理缺失值
2019/07/31 Python
Python 存取npy格式数据实例
2020/07/01 Python
美国精品家居用品网站:US-Mattress
2016/08/24 全球购物
香港礼品网站:GiftU eshop
2017/09/01 全球购物
商场经理竞聘演讲稿
2014/01/01 职场文书
医院学雷锋活动策划方案
2014/02/15 职场文书
服装促销活动方案
2014/02/23 职场文书
2015年财务试用期工作总结
2014/12/24 职场文书
幼儿园大班教师个人工作总结
2015/02/05 职场文书
2015年物资管理工作总结
2015/05/20 职场文书
对象析构函数__del__在Python中何时使用
2022/03/22 Python
解决springboot druid数据库连接失败后一直重连的方法
2022/04/19 Java/Android