Vue中使用自定义指令directives 实现兼容PC和移动端的触摸滑动事件

2,822 阅读2分钟

前言

H5提供了touch事件来进行移动端的交互,但touch事件在pc上是无效的 pc上可以使用mouse事件实现同样的效果,可以在使用的时候判断是否为移动端来切换对应的事件,这样写的坏处不用多说 不优雅也不好用

vue提供了许多指令来便于我们的开发 -比如v-for v-if v-bind···等等

同时也提供了自定义指令 directives 来供我们实现我们所想要的

通过指令我们可以在元素渲染完成时给元素添加触摸事件,在指令内部完成事件的判断和绑定

实现过程

定义一个局部指令movebind为渲染完成后的钩子函数el为绑定的元素 binding可以理解为传入的参数

<!--在模版中使用注意要加上 v- -->
<div class="container" v-move="{start,move,end}"></div>  
export default {
 directives: {
  move: {
            bind: (el, binding) => {
    /**
     *  判断是PC端还是移动端
     *  通过不同的设备定义不同的事件名
     */
    const isMobile =
     navigator.userAgent.match(
      /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
     ) !== null
    const [start, move, end] = isMobile
     ? ['touchstart', 'touchmove', 'touchend']
     : ['mousedown', 'mousemove', 'mouseup']
    /**
     *  开始触摸
     *  执行触摸回调函数
     *  监听滑动事件
     *  监听触摸结束事件
     *  监听阻止移动端屏幕移动事件
     */
    const startFun = e => {
     binding.value.start(e)
     el.addEventListener(move, moveFun)
     el.addEventListener(end, endFun)
     window.addEventListener('touchmove', prevent, {
      passive: false
     })
    }
    /**
     *  开始滑动
     *  执行滑动回调函数
     */
    const moveFun = e => {
     binding.value.move(e)
    }
    /**
     *  结束触摸
     *  执行结束触摸回调函数
     *  销毁滑动事件
     *  销毁结束触摸事件
     *  销毁阻止移动屏幕事件
     */
    const endFun = e => {
     binding.value.end(e)
     el.removeEventListener(move, moveFun)
     el.removeEventListener(end, endFun)
     window.removeEventListener('touchmove', prevent)
    }
    /**
     *  阻止移动端屏幕移动
     */
    const prevent = e => {
     e.preventDefault()
    }
    /**
     *  监听触摸事件
     */
    el.addEventListener(start, startFun)
   }
  }
 },
 methods: {
     /**
      *  事件的回调 在这里执行你的代码
      */
  start: function(e) {
   console.log(e)
  },
  move: function(e) {
   console.log(e)
  },
  end: function(e) {
   console.log(e)
  }
 }
}

注意事项

  1. 在移动端可能会有触摸移动时同时触发屏幕的移动所以用到了阻止移动屏幕的事件
  2. 为了性能优化,只在开始时监听开始触摸事件,然后开始触摸时再监听其他事件,最后再结束触摸时销毁这些事件
  3. 自定义指令中无法访问到 this 所以业务逻辑写在回调函数中比较合适

不断成长中,且行且珍惜