uni-app项目中封装手势滑动组件

小程序原生api中没有封装手势滑动组件

手势封装的思路

  1. 给容器绑定两个触屏事件 touchstart 和 touchend
  2. 用户按下屏幕事件
    按下时间: Date.now() 时间戳
    按下坐标: clientX 和 clientY
  3. 用户离开屏幕事件
    离开时间: Date.now()
    离开坐标: clientX 和 clientY
    根据两个时间运算判断用户按下屏幕时长是否合法
    根据两对坐标判断距离是否合法 判断用户滑动方向
<!-- demo.vue-->
<template>
  <view
    @touchstart="handletouchstart"
    @touchend="handletouchend"
  >
    demo-demo
  </view>
</template>
<script>
/*
  1. 给容器绑定两个触屏事件 touchstart 和 touchend
  2. 用户按下屏幕事件
    按下时间: Date.now() 时间戳 1970 -1-1 到现在的毫秒数
    按下坐标: clientX 和 clientY
  3. 用户离开屏幕事件
    离开时间: Date.now()
    离开坐标: clientX 和 clientY
    根据两个时间运算判断用户按下屏幕时长是否合法
    根据两对坐标判断距离是否合法 判断用户滑动方向
*/
export default {
     
     
  data () {
     
     
    return {
     
     
      startTime: 0, // 按下的时间
      startX: 0, // 按下x坐标
      startY: 0 // 按下y坐标
    }
  },
  methods: {
     
     
    handletouchstart (event) {
     
     
      console.log('按下-----')
      this.startTime = Date.now()
      const touch = event.changedTouches[0]
      this.startX = touch.clientX
      this.startY = touch.clientY

    },
    handletouchend (event) {
     
     
      console.log('松开---------')
      const endTime = Date.now();
      const touch = event.changedTouches[0]
      const endX = touch.clientX
      const endY = touch.clientY
      // 如果按下时长超过2秒则不合法不触发
      if (endTime - this.startTime > 2000) return
      // 滑动的方向
      let direction = ''
      // 判断滑动距离 如果小于10则距离不合法不触发 滑动方向 注意:要加上绝对值
      console.log('绝对值', Math.abs(endX - this.startX))
      // 判断滑动距离 是否合法 滑动方向 注意:要加上绝对值
      if (!(Math.abs(endX - this.startX) > 10 && Math.abs(endY - this.startY < 10))) return
      // 滑动方向
      direction = endX - this.startX > 0 ? 'right' : 'left'
      console.log(direction)
    }
  }
}
</script>

<style>
view {
     
     
  width: 100%;
  height: 500rpx;
  background-color: lightblue;
}
</style>

手势封装的方法

  1. 在 src 根目录下新建 components目录,存放公共组件
<!-- src/components/swiperAction.vue -->
<template>
  <view
    @touchstart="handletouchstart"
    @touchend="handletouchend"
  >
    <slot></slot>
  </view>
</template>

<script>
export default {
     
     
  data () {
     
     
    return {
     
     
      startTime: 0, // 按下时间
      startX: 0, // 按下x坐标
      startY: 0 // 按下y坐标
    }
  },
  methods: {
     
     
    handletouchstart (event) {
     
     
      this.startTime = Date.now()
      const touch = event.changedTouches[0]
      this.startX = touch.clientX
      this.startY = touch.clientY

    },
    handletouchend (event) {
     
     
      const endTime = Date.now();
      const touch = event.changedTouches[0]
      const endX = touch.clientX
      const endY = touch.clientY
      // 如果按下时长超过2秒则不触发
      if (endTime - this.startTime > 2000) return
      // 滑动的方向
      let direction = ''
      // 判断滑动距离 如果小于10则距离不合法不触发 滑动方向 注意:要加上绝对值
      if (Math.abs(endX - this.startX) < 10) return
      // 滑动方向
      direction = endX - this.startX > 0 ? 'right' : 'left'
      this.$emit('swiperAction', {
     
      direction }) // 向父组件中传值 
    }
  }
}
</script>

<style>
</style>
  1. 自定义手势滑动组件的使用
<!-- src/pages/imgDetail/index.vue 需要左右滑动来查看图片的父组件 -->
<template>
  <view>
    <!-- 高清大图 开始 -->
    <view class="high_img">
      <!-- 3. 使用 并绑定子组件向父组件传值的自定义事件接收 direction 参数 -->
      <swiper-action @swiperAction="handleSwiperAction">
        <image
          mode="widthFix"
          :src="imgDetail.thumb"
        ></image>
      </swiper-action>
    </view>
    <!-- 高清大图 结束 -->
    <!-- ... -->
</template>

<script>
import swiperAction from '@/components/swiperAction.vue' // 1. 引入

export default {
     
     
  components: {
     
      swiperAction }, // 2. 注册
  data () {
     
     
    return {
     
     
      imgDetail: [],      // 图片信息对象
      imgIndex: 0 // 当前图片索引
    }
  },
 onLoad () {
     
     
    // console.log(getApp().globalData)
    const {
     
      imgIndex } = getApp().globalData
    this.imgIndex = imgIndex
    this.getData()
  },
  methods: {
     
     
    getData () {
     
      // 给当前页面赋值
      const {
     
      imgList } = getApp().globalData
      this.imgDetail = imgList[this.imgIndex]
      this.getComments(this.imgDetail.id)
    },
    getComments (id) {
     
     
    	console.log('根据id查询当前页的其他数据', id)
    },
    handleSwiperAction (obj) {
     
      // 4. 接收参数
      console.log(obj) // { direction:"left" }
      const direction = obj.direction
      // 左滑 imgIndex ++
      // 右滑 imgIndex -- 
      // 判断数组是否越界
      const {
     
      imgList } = getApp().globalData
      if (direction === 'left' && this.imgIndex < imgList.length - 1) {
     
     
        this.imgIndex ++
        this.getData() // 刷新数据
      } else if (direction === 'right' && this.imgIndex > 0) {
     
     
        this.imgIndex --
        this.getData() // 刷新数据
      } else {
     
     
        uni.showToast({
     
      title: '没有更多数据了', icon: 'none' })
      }
    }
  }
}
</script>
<style lang="scss" scoped >
</style>

over
作为学习笔记记录一下,以后有好的方法再更新。

猜你喜欢

转载自blog.csdn.net/tyoubinn/article/details/109057823