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中普通函数的使用介绍
Dec 19 Javascript
引入JS文件IE6报语法错误或缺少对象问题的解决方法
Jan 09 Javascript
对table和ul实现js分页示例分享
Feb 24 Javascript
用循环或if语句从json中取数据示例
Aug 18 Javascript
jQuery遍历DOM元素与节点方法详解
Apr 14 Javascript
BootStrap 可编辑表Table格
Nov 24 Javascript
jQuery实现拖拽可编辑模块功能代码
Jan 12 Javascript
JavaScript中递归实现的方法及其区别
Sep 12 Javascript
浅析node.js的模块加载机制
May 25 Javascript
微信小程序自定义可滑动日历界面
Dec 28 Javascript
vue中typescript装饰器的使用方法超实用教程
Jun 17 Javascript
vue-cli3项目升级到vue-cli4 的方法总结
Mar 19 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使之能同时支持GIF和JPEG
2006/10/09 PHP
PHP中如何判断AJAX提交的数据
2012/02/05 PHP
php中jQuery插件autocomplate的简单使用笔记
2012/06/14 PHP
php mssql扩展SQL查询中文字段名解决方法
2012/10/15 PHP
PHP的serialize序列化数据以及JSON格式化数据分析
2015/10/10 PHP
PHP手机号中间四位用星号*代替显示的实例
2017/06/02 PHP
PHP实现基于PDO扩展连接PostgreSQL对象关系数据库示例
2018/03/31 PHP
实例分析PHP将字符串转换成数字的方法
2019/01/27 PHP
JavaScript 图片预览效果 推荐
2009/12/22 Javascript
jquery中 $.expr使用实例介绍
2014/06/09 Javascript
AngularJS中取消对HTML片段转义的方法例子
2015/01/04 Javascript
js中的事件捕捉模型与冒泡模型实例分析
2015/01/10 Javascript
jQuery点击输入框显示验证码图片
2016/05/19 Javascript
javaScript给元素添加多个class的简单实现
2016/07/20 Javascript
jQuery模拟html下拉多选框的原生实现方法示例
2019/05/30 jQuery
Vue.js+cube-ui(Scroll组件)实现类似头条效果的横向滚动导航条
2019/06/24 Javascript
Node.js 实现简单的无侵入式缓存框架的方法
2019/07/21 Javascript
Vue的双向数据绑定实现原理解析
2020/02/17 Javascript
js实现随机点名器精简版
2020/06/29 Javascript
Vue获取微博授权URL代码实例
2020/11/04 Javascript
零基础写python爬虫之使用Scrapy框架编写爬虫
2014/11/07 Python
python 文件操作api(文件操作函数)
2016/08/28 Python
Python 比较文本相似性的方法(difflib,Levenshtein)
2018/10/15 Python
浅谈django rest jwt vue 跨域问题
2018/10/26 Python
Python设计模式之解释器模式原理与用法实例分析
2019/01/10 Python
在pycharm下设置自己的个性模版方法
2019/07/15 Python
django 类视图的使用方法详解
2019/07/24 Python
CSS3实现可关闭的下拉手风琴菜单效果
2015/08/31 HTML / CSS
HTML5微信播放全屏问题的解决方法
2017/03/09 HTML / CSS
计算机专业学生的自我评价
2013/12/15 职场文书
活动邀请函范文
2014/01/19 职场文书
2015年银行信贷员工作总结
2015/05/19 职场文书
礼仪培训心得体会
2016/01/22 职场文书
Python Pycharm虚拟下百度飞浆PaddleX安装报错问题及处理方法(亲测100%有效)
2021/05/24 Python
python pygame 开发五子棋双人对弈
2022/05/02 Python
win11自动弹出虚拟键盘怎么关闭? Win11关闭虚拟键盘的技巧
2023/01/09 数码科技