• vue指令实现拖动的高级写法


    不熟悉vue自定义指令看这里: https://cn.vuejs.org/v2/guide/custom-directive.html

    vue指令实现拖动方法很方便也挺简单,但是网上大部分的教程代码,一般都是把代码全部写一个方法里面,代码不够美观,代码逻辑也不太清晰,不推荐这种写法,比如下面这样:

    Vue.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;
         };
        };
       }
      }
     }

    这里介绍一种比较方美观,逻辑清晰的写法,代码如下:

    Vue.directive('drag', {
      bind (el, binding) {
        el.style.cursor = 'move'
        el.style.position = 'fixed'
        el.mousedownPoint = {
          x: 0,
          y: 0
        }
        // bind 改变函数内部 this 指向,让 this 指向 el
        // el.handleMouseup, el.handleMousemove, el.handleMousedown 这三个可以是其他的全局变量
        el.handleMouseup = handleMouseup.bind(el)
        el.handleMousemove = handleMousemove.bind(el)
        el.handleMousedown = handleMousedown.bind(el)
        el.addEventListener('mousedown', el.handleMousedown)
        document.body.addEventListener('mouseup', el.handleMouseup)
        document.body.addEventListener('mousemove', el.handleMousemove)
      },
      unbind (el) {
        document.body.removeEventListener('mouseup', el.handleMouseup)
        document.body.removeEventListener('mousemove', el.handleMousemove)
      }
    });
    const handleMousedown = function (e) {
       // 这里的this被bind改变了,是el
       // 这里的e是 MouseEvent 对象
      const initialPosition = this.getBoundingClientRect()
      this.style.width = initialPosition.width + 'px'
      this.position = {
        left: initialPosition.left,
        top: initialPosition.top
      }
      this.readyToMove = true
      this.mousedownPoint.x = e.screenX
      this.mousedownPoint.y = e.screenY
    }
    const handleMousemove = function (e) {
      if (!this.readyToMove) return false
      const position = this.position
      position.left = position.left + e.screenX - this.mousedownPoint.x
      position.top = position.top + e.screenY - this.mousedownPoint.y
      this.mousedownPoint.x = e.screenX
      this.mousedownPoint.y = e.screenY
      this.style.left = position.left + 'px'
      this.style.transform = 'none'
      this.style.marginLeft = 0
      this.style.marginTop = 0
      this.style.top = position.top + 'px'
      this.style.bottom = 'auto'
      this.style.right = 'auto'
    }
    const handleMouseup = function (e) {
      this.readyToMove = false
    }

    这种写法主要利用了bind的特性,回一个新的函数,并且这个函数的 this 已经被改成我们想要的 this, 推荐这种写法。

  • 相关阅读:
    Linux 文件管理篇(一 档案读写)
    Linux 任务管理篇(一)
    Mysql 视图简介
    MySql 使用正则表达式查询
    mysql 插入、更新与删除数据
    mysql 多表查询
    mysql 单表查询
    Java抽象类与接口
    maven小结
    shiro 进行权限管理 —— 使用BigInteger进行权限计算获取菜单
  • 原文地址:https://www.cnblogs.com/yalong/p/11346765.html
Copyright © 2020-2023  润新知