vue better-scroll-滚动组件 的使用和可滚动区域的问题

一.浏览器滚动原理

​ 当页面内容的高度超过视口高度的时候,会出现纵向滚动条;当页面内容的宽度超过视口宽度的时候,会出现横向滚动条。也就是我们的视口展示不下内容的时候。会通过滚动条的方式让用户滚动屏幕看到剩余的内容。

二.安装

npm install better-sroll --save

三.引用

import BScroll from 'better-scroll'

四.使用

	let scroll = new BScroll(DOM,{})

		
    mounted(){
		// 在这个方法中操作,不能在created中操作,因为created是组件加载完成的时候执行,而这个时候template还没有加载,无法找到DOM文档
    }
	<div class="content">	//最外层必须设置一个高度,要不然不会有滑动效果,里面的元素必须只有一个ul要不然会出错
        <ul>				
            <li>...li>
            <li>...li>
            ...
        ul>
    div>
	<script>
        //默认情况下BScroll是不可以实时的监听滚动位置
        //probeType:侦测属性的意思
        //参数有:
        //0,1: 都是不侦测实时的位置
        //2:在手指滚动的过程中检测,手指离开后的惯性滚动过程中不侦测
        //3:只要是滚动都检测
        
        document.querySelector('.wrapper')  //这个容易出错,因为在Vue里面会出现多个相同名称的他不一定是取到的你想要的元素
        
        const bscroll = new BScroll(document.querySelector('.content'),{
            click:ture			//必须加上这个,要不然组件里其他的点击事件都不能点击了
            					//button无论是false还是true都是可以点击的,但是div还有其他组件都是必须设置为true才可以点击
            probeType:3,
            pullUpLoad:ture		//上拉加载更多必须要这个属性,值必须为ture
        })
        
        bscroll.on('scroll',(position) =>{
            position //这个代表着滚动到页面的哪里了
        })
        
        bscroll.on('pullingUp',()=>{
            console.log('上拉加载更多');
            //这里可以发送网络请求,请求更多的类容
            
            // 等数据请求完成,并且将新的数据展示出后
            
            bscroll.finishPullUp();//必须执行这个方法,要不然只会执行一次上拉加载更多
        })
        
	script>

五.会出现的问题

5.1 new BScroll(document.querySelector(’.content’)) 里面参数的问题

document.querySelector(’.wrapper’) 这个容易出错,因为在Vue里面会出现多个相同名称的他不一定是取到的你想要的元素

​ 解决方案:

​ 在元素上加上ref属性

​ ref如果是绑定在组件中的,那么通过this.$refs.refname获取到的是一个组件对象.

​ ref如果是绑定在普通元素中,那么通过this.$refs.refname获取到的是一个元素对象.

5.2 Better-Scroll可滚动区域的问题

  • Better-Scroll 在决定有多少区域可以滚动时,是根据scrollHeight属性决定的

    • scrollHeight属性是根据放在Better-Scroll中content中的子组件的高度来决定
    • 但是我们首页中,刚开始计算scrollHeight属性时,是没有将图片计算在内
    • 因为图片还没有加载出来(网速和服务器的原因),这个时候计算的高度是不够的
    • 当图片加载进来之后,有了新的高度,但是scrollHeight属性并没有进行跟新,还是开始计算的高度
    • 它可以滚动的区域只有最开始计算的高度
    • 所以会出现可滚动区域的问题
  • 如何解决这个问题?

    • 监听每一张图片是否加载完成,只要有一张图片加载完成,执行一次refresh()
    • 如何监听图片加载完成?
      • 原生Js监听图片:img.onload = function(){}
      • Vue中监听图片 :@load = “方法”
    • 调用scroll的refresh()
  • 如何将GoodsListItem.vue 中的事件传入到Home.vue中?

    • 因为涉及到非父子组件的通信,所以这里选择了总线事件

    • $bus => 总线

    • 第一步:在main.js中创建一个事件总线 Vue.prototype.$bus = new Vue()

    • 第二步:在需要监听图片加载的地方给事件总线添加事件

    • <img src="" @load="imageLoad">
      
      imageLoad(){
        this.$bus.$emit('itemImageLoad'
      }
      
    • 第三步,给事件总线绑定监听

    • created() {
          this.$bus.$on('itemImageLoad', () => {
            // 调用.refresh()这个方法,刷新 scrollHeight 可滚动高度
            this.$refs.scroll.refresh()
          })
      }
      
  • 对于 refresh 非常频繁的问题,进行防抖操作

    • 防抖函数 debounce / 节流函数 throttle

    • 防抖动函数起作用的过程

      • 如果我们直接执行 refresh ,那么 refresh 将会执行很多次,执行非常频繁,对服务器压力太大了
      • 可以将 refresh 函数传入到 debounce 函数中,生成一个新的函数.
      • 之后在调用非常频繁的时候,就使用新产生的函数
      • 而新生成的函数,并不会非常频繁的调用,如果下一次执行来的非常的快,那么会将上一次取消
      meounted() {
          // 调用防抖动函数,来避免多次执行
          const refresh = this.debounce(this.$refs.scroll.refresh,20)
          // 监听goods中图片是否加载完成
          this.$bus.$on('itemImageLoad', () => {
              // 调用.refresh()这个方法,刷新 scrollHeight 可滚动高度
              refresh()
          })
      }
      
      
      debounce(func, delay) {  				// func:传入的函数     delay:延迟的时间
          let time = null						//设置一个时间参数
          return function (...args) {			//返回一个函数
              if (time) clearTimeout(time)	//第一次是空值,判断time是否有值,有就就会清楚计时器
              time = setTimeout(()=>{			// 给time加一个定时器
                  func.apply(this,args)		//异步执行传进来的方法
              },delay)
          }
      }
      

你可能感兴趣的:(前端)