vue 自定义指令 - 移动端 touch拖拽

315 阅读2分钟

先看一下内置指令

v-bind: 简写 : 可设置自定义属性
v-on: 用于监听事件  v-on:click  v-on:keyup
v-model:对表单元素实现双向数据绑定,
(也可以自己封装一个,大概思路是通过input事件将表单元素的value传给子组件,
子组件通过$emit派发input)
v-show:判断条件是否成立,不成立时候会给DOM设置css的style属性display:none
v-if: 判断条件是否成立,不成立时候会直接删除dom元素
v-for:循环指令
v-text:更新元素的textContent
v-html:更新元素的innerHTML;
......

这里用的是全局自定义指令,考虑到把代码全部写到main.js中的话,代码量有点多,然后创建一个单独的drag.js的文件。

实现拖拽的原理:
   三大事件:
   mousedown(鼠标按下),
   mousemove(鼠标移动),
   mouseup(鼠标抬起)
   通过获取鼠标位置来动态改变dom样式
export default {
  //被绑定元素插入父节点时调用
  inserted (el) {
    const switchPos = {
      x: 0,
      y: 0,
      startX: 0,
      startY: 0,
      endX: 0,
      endY: 0
    }
    el.addEventListener('touchstart', function (e) {
      console.log(e)
      switchPos.startX = e.touches[0].pageX
      switchPos.startY = e.touches[0].pageY
    })
    el.addEventListener('touchend', function (e) {
      switchPos.x = switchPos.endX
      switchPos.y = switchPos.endY
      switchPos.startX = 0
      switchPos.startY = 0
    })
    el.addEventListener('touchmove', function (e) {
      if (e.touches.length > 0) {
        const offsetX = e.touches[0].pageX - switchPos.startX
        const offsetY = e.touches[0].pageY - switchPos.startY
        let x = switchPos.x - offsetX
        let y = switchPos.y - offsetY
        if (x + el.offsetWidth > document.documentElement.offsetWidth) {
          x = document.documentElement.offsetWidth - el.offsetWidth
        }
        if (y + el.offsetHeight > document.documentElement.offsetHeight) {
          y = document.documentElement.offsetHeight - el.offsetHeight
        }
        if (x < 0) { x = 0 }
        if (y < 0) { y = 0 }
        el.style.right = x + 'px'
        el.style.bottom = y + 'px'
        switchPos.endX = x
        switchPos.endY = y
        e.preventDefault()
      }
    })
  }
}

指令写好了,我这里是在main.js全局注册指令,所以需要引入一下。

import vDrag from '@/directive/drag'
Vue.directive('指令名', vDrag)
Vue.directive('drag', vDrag)

然后在组件中通过 v-指令名,这里的指令明就是在main.js中定义的指令名

比如:

<div v-drag></div>
//这样的话这个div就可以拖拽了

需要注意的是要改变div的位置,所有要让div脱离文档,设置定位:position:absolute,如果不设置的话,拖拽是没有效果的。