在vue中封装一个betterscroll组件,并解决ios、Android在微信页面上下拉出现滑动的问题

最近在开发微信公众号网页的时候,发现使用原生滚动的时候,ios在微信网页下,上拉,下拉都会出现一大片的空白,看起来极其的别扭,为了解决这一问题,找了许多参考资料,如下是解决方法。

1.首先在你需要禁止滑动的页面中添加如下代码

mounted(){
   document.body.addEventListener(
        'touchmove',
        function (e) {
          e.preventDefault()
        },
        { passive: false }
      )
}

当你设置完后会发现,ios\Android下页面确实不能上拉下拉了,但是页面也不能滑动了,大部分博客告诉完你这个方法之后都不会告诉你接下来的解决办法,实属坑人啊,以下是我的解决方法。因为上面那个代码会把所有原生的滚动都禁止掉,所以这里我建议用betterscroll代替原生的滚动。

2.安装betterscroll代替原生的scroll,这样页面就可以滑动了

npm install better-scroll

然后我把betterscroll组件封装了一下

<!--
    参数解释在props中
    使用说明:
      <scroll
      class="wrapper"
      :data="data"
    >
      <div class="content">
      </div>
    </scroll>

    要想betterScroll产生滚动效果,你需要设置'.wrapper'的高度,content的内容高度必须要高于warpper的高度才会显示出滚动条
    如果content里面内容的高度是不固定的,那么需要给scroll传值data
-->
<template>
  <div ref="wrapper" class="scroll">
    <div class="scroll-wrap">
      <slot></slot>
    </div>
  </div>
</template>

<script>
import BScroll from 'better-scroll'
export default {
  props: {
    /*    传1 滚动的时候会派发scroll事件,会截流。
          传2 滚动的时候实时派发scroll事件,不会截流。
          传3 除了实时派发scroll事件,在swipe的情况下仍然能实时派发scroll事件     */
    probeType: {
      type: Number,
      default: 1
    },
    //  点击列表是否派发click事件
    click: {
      type: Boolean,
      default: true
    },
    //  是否开启横向滚动
    scrollX: {
      type: Boolean,
      default: false
    },
    //  是否派发滚动事件
    listenScroll: {
      type: Boolean,
      default: false
    },
    //  列表的数据,用于数据改变导致视图更改后重新初始化滚动
    data: {
      type: Array,
      default: null
    },
    /** * 是否派发滚动到底部的事件,用于上拉加载 */
    pullup: {
      type: Boolean,
      default: false
    },
    /** * 是否派发顶部下拉的事件,用于下拉刷新 */
    pulldown: {
      type: Boolean,
      default: false
    },
    /** * 是否派发列表滚动开始的事件 */
    beforeScroll: {
      type: Boolean,
      default: false
    },
    /** * 当数据更新后,刷新scroll的延时。 */
    refreshDelay: {
      type: Number,
      default: 20
    }
  },
  watch: {
    // 监听数据的变化,延时refreshDelay时间后调用refresh方法重新计算,保证滚动效果正常
    data () {
      setTimeout(() => {
        this.refresh()
      }, this.refreshDelay)
    }
  },
  mounted () {
    // 保证在DOM渲染完毕后初始化better-scroll
    setTimeout(() => {
      this._initScroll()
    }, 20)
  },
  methods: {
    _initScroll () {
      if (!this.$refs.wrapper) {
        return
      }
      // better-scroll的初始化
      this.scroll = new BScroll(this.$refs.wrapper, {
        probeType: this.probeType,
        click: this.click,
        useTransition: false, // 防止iphone微信滑动卡顿
        scrollX: this.scrollX,
        preventDefault: true,
        momentum: true,
        bounce: false // 阻止scroll的弹性动画
      })
      // 是否派发滚动事件
      if (this.listenScroll) {
        const me = this
        this.scroll.on('scroll', pos => {
          me.$emit('scroll', pos)
        })
      }
      // 是否派发滚动到底部事件,用于上拉加载
      if (this.pullup) {
        this.scroll.on('scrollEnd', () => {
          // 滚动到底部
          if (this.scroll.y <= this.scroll.maxScrollY + 50) {
            this.$emit('scrollToEnd')
          }
        })
      }
      // 是否派发顶部下拉事件,用于下拉刷新
      if (this.pulldown) {
        this.scroll.on('touchend', pos => {
          // 下拉动作
          if (pos.y > 50) {
            this.$emit('pulldown')
          }
        })
      }
      // 是否派发列表滚动开始的事件
      if (this.beforeScroll) {
        this.scroll.on('beforeScrollStart', () => {
          this.$emit('beforeScroll')
        })
      }
    },
    disable () {
      // 代理better-scroll的disable方法
      this.scroll && this.scroll.disable()
    },
    enable () {
      // 代理better-scroll的enable方法
      this.scroll && this.scroll.enable()
    },
    refresh () {
      // 代理better-scroll的refresh方法
      this.scroll && this.scroll.refresh()
    },
    scrollTo () {
      // 代理better-scroll的scrollTo方法
      this.scroll && this.scroll.scrollTo.apply(this.scroll, arguments)
    },
    scrollToElement () {
      // 代理better-scroll的scrollToElement方法
      this.scroll && this.scroll.scrollToElement.apply(this.scroll, arguments)
    }
  }
}
</script>

<style lang="less" scoped>
.scroll {
  overflow: hidden;
}
</style>

使用的例子都在上面的代码里面了,如果你有很多地方需要使用到这个组件,你可以在main.js里面全局使用这个组件

import scroll from 'components/Scroll.vue'
Vue.component('scroll', scroll)

最后按照代码的方法使用这个组件,就能够很完美的解决页面上拉下拉出现滑动的问题。

上一篇:变量和简单数据类型


下一篇:Dart Set方法