• 【Vue项目复习笔记】滚动区域的Bug分析与解决


    因为上一次解决的滚动区域bug是依靠第三方里面的东西,现在我们不依靠第三方的东西如何解决呢?

    首先:我们先要把项目中的关于加载更多的内容删掉,然后不依靠第三方的东西完成此次功能
    此时出现以下情况:
    请添加图片描述
    我们此时查看一下BScroll里面的scrollerHeight值

    在这里插入图片描述
    此时这个scrollerHeight的高度是1464,这个高度是不包括图片的高度,因为这在better-scroll中只能滚动1464,但是我们真实的滚动高度远远不止1464,所以这个时候就出现了问题。
    在这里插入图片描述
    那我们怎么才能让其把这个高度重新计算一次呢?
    我们只需要执行一次

    this.scroll.refresh()
    
    • 1

    等把所有的图片加载完成以后执行一次refresh(),一旦我们执行了这个refresh()以后,它内部就会根据我们最新的子组件,我们的GoodlistItem重新计算最新高度。那么问题又来了,我怎么知道我的图片加载完成了?我们必须要将图片加载完成和我们的refresh()对应起来。
    我们第一步先要监听图片加载,这个滚动的图片是在我们的GoodsListItem组件中的img中,所以有:

     <img :src="goodsItem.show.img" @load="imageLoad">
    
    • 1

    在这里插入图片描述
    怎么才能将图片加载完成和我们的refresh()对应起来,第一种方法是,将我们的图片加载完成以后执行的this.scroll.refresh()这个事件传给他的父组件GoodsList,然后再通过父子组件传值将其传给Home.vue,然后首页就能通过this.$refs.scroll.refresh()拿到这个值,但是这样就特别麻烦。我们也可以用Vuex对象,它可以用来记录一些状态,一旦GoodsListItem图片加载完成了以后,就改变Vuex里面的某一个属性,再让我们的首页里面应用这一属性,并让它实时监听我们Vuex里面的某个属性的改变,一旦这个属性发生变化,就让其执行this. $refs.scroll.refresh()。也就意味着我们用Vuex做了中间的一个通信,在GoodsListItem中拿到this. $store,就可以改变Vuex里面的属性,再让首页监听这个属性。另外,我们还可以用 事件总线 ,它和Vuex的作用很像,但是它不是用来管理状态的,它是用来管理事件的。我们通过this. b u s . bus. bus. emit(‘aaa’)向事件总线发送事件,然后我们可以在首页里面监听它发射出来的事件,用this. $bus.on(‘aaa’)对aaa这个事件进行监听。
    所以在GoodsListItem.vue中发射事件:

      methods: {
        imageLoad() {
          this.$bus.$emit('itemImageLoad')
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在我们的Home.vue中进行监听:

     mounted() {
          this.$bus.$on('itemImageLoad', () => {
            this.$refs.scroll.refresh()
          })
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (之所以在mouted而不在created中是因为在created中很有可能是拿不到this. $ refs.scroll)
    但是在我们的程序中是没有$bus这种东西的,所以我们需要以下操作:
    在 main.js 中将 $bus 绑定到 vue 原型上

    Vue.prototype.$bus = new Vue();
    
    • 1

    再到scroll.vue中封装refresh()方法

    refresh(){
          this.scroll.refresh()
        },
    
    • 1
    • 2
    • 3

    最终的结果:
    请添加图片描述
    总结:
    解决首页中Better-Scroll可滚动区域的问题
    ●Better-Scroll在决定有多少区域可以滚动时,是根据scrollerHeight属性决定

    • scrollerHeight属性是根据放Better-Scroll的content中的子组件的高度
    • 但是我们的首页中,刚开始在计算scrollerHeight属性时,是没有将图片计算在内的
    • 所以,计算出来的结果是错误的(1400+)
    • 后来图片加载进来之后有了新的高度但是scrollerHeight属性并没有进行更新。
    • 所以滚动出现了问题

    ●如何解决这个问题了?

    • 监听每一张图片是否加载完成,只要有一张图片加载完成了,执行一 次refresh()
    • 如何监听图片加载完成了?
      原生js监听:img.onload = function) {}
      vue中监听:@load=‘方法’
      ●调用scroll的refresh()

    ●如何将GoodsListltem.vue中 的事件传入到Home.yue中

     * 因为涉及到非父子组件的通信,所以这里我们选择了事件总线
        - bus->.总线
        - Vue.prototype.$bus = new Vue()
        - this.bus.emit(事件名称',参数)
        - this.bus.on(事件名称,回调函数(参数))
    
    • 1
    • 2
    • 3
    • 4
    • 5

    优化:
    我们监听item中图片加载完成这个事件调用的频率很高

     mounted() {
          this.$bus.$on('itemImageLoad', () => {
            this.$refs.scroll.refresh()
          })
    
    • 1
    • 2
    • 3
    • 4

    在home组件中的methods中

      //防抖函数
        debounce(func,delay){
          let timer=null;
          return function(...args){
            if(timer) clearTimeout(timer)
    
            timer=setTimeout(()=>{
              func.apply(this.args)
            },delay)
          }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    然后在mouted中使用该防抖函数

      mounted() {
        this.$bus.$on('itemImageLoad',()=>{
          this.$refs.scroll.refresh()
        })
          const refresh=this.debounce(this.$refs.scroll.refresh,500)
          this.$bus.$on('itemImageLoad',()=>{
              refresh()
        })
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    总结:

    • 对于refresh非常频繁的问题,进行防抖操作
      - 防抖函数起作用的过程:
      ■如果我们直接执行refresh,那么refresh函数会被执行30次.
      ■可以将refresh函数传入到debounce函数中, 生成一个新的函数.
      ■之后在调用非常频繁的时候,就使用新生成的函数
      ■而新生成的函数,并不会非常频繁的调用,如果下一次执行来的非常快,那么会将上一次取消掉
  • 相关阅读:
    java中的io流
    贪吃蛇项目实践
    Day2力扣打卡
    nestJs(一) 创建node项目
    【C++项目实现】推箱子
    【Java 进阶篇】JQuery 案例:下拉列表选中条目左右移动,打破选择的边界
    华为数通方向HCIP-DataCom H12-831题库(多选题:41-60)
    [Qt基础-07 QSignalMapper]
    支持typecho博客的黑白模式纪念日插件
    云原生kubernetes从入门到实践系列教程
  • 原文地址:https://blog.csdn.net/qq_40992225/article/details/126212105