• 页面触底自动加载 Vue 组件


    不管是 web 端还是移动端,信息流都是现在很流行的信息展示方式。信息流经常搭配自动加载一起使用以获得更好的使用体验。

    最近在使用 Vue 开发过程中也遇到了首页信息流自动加载的需求。大致了解了一下几个滚动自动加载组件,发现多数都是把内容放在在一个单独的滚动容器内;但我遇到的需求是整个页面的滚动(博客列表首页那种),不是限制在容器内,不太符合。把整个页面放进滚动容器明显很奇怪,只是为了一个简单的下拉加载不值当。所以参考网上的一些介绍实现了一个几十行的简单小组件 ButtomDetector 来实现这个功能,同时也方便在多个需要到底自动加载的页面中进行复用。

    实现原理
    实现原理非常简单:

    • 监听页面的滚动事件
    • 在触发滚动时,调用 DOM api 来获取页面的滚动状态
    • 如果已经滚动到底,抛出事件供页面使用
    JS 事件监听
    
    • 1
    // 监听 scroll 事件,绑定回调函数
    window.addEventListener('scroll', this.listenBottomOut)
    
    // 取消事件监听
    window.removeEventListener('scroll', this.listenBottomOut, false)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    页面滚动状态
    DOM 提供了获取页面元素滚动状态的相关属性,这里主要用到以下三个:scrollHeight 滚动内容高度,scrollTop 滚动内容顶部离显示区域的距离,clientHeight 显示区域高度。如下图所示。

    在这里插入图片描述
    因此,判断滚动到底就很简单了:

    if (scrollTop + clientHeight >= scrollHeight - delta) {
        // emit bottom event
    }
    
    
    • 1
    • 2
    • 3
    • 4

    其中 delta 的作用是可以在快到底端(例如还有50px)时提前进行加载,避免拉到底后等待加载的这段时间。

    一些细节问题#
    重复抛出事件#
    因为监听的是 scroll 事件,并且使用 delta 做了一点提前加载,因此可能会触发多次触底事件(距离底部48px, 30px, 12px… 都符合判断条件),造成页面重复多次加载数据。因此选择在组件中增加一个 loadingMore 属性,表示父页面正在加载数据,此时不再继续抛出事件;当页面完成加载后,将 loadingMore 重置为 false 以继续监听触底。

    没有更多数据#
    在信息流已经到底,没有更多数据的时候,触底事件就没有作用了。当然这个判断也可以在父页面中进行,当没有更多数据时不再继续处理触底事件;不过为了方便页面中的加载数据方法(不用每次都单独判断是否有更多),给组件增加一个 noMore 参数,此时不再抛出触底事件。

    代码实现

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    页面使用
    从触底功能上来说,detector 组件放在页面中的任何位置都可以。放在信息流下方的话还可以顺便做加载动画和信息到底的提示信息。

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    getMoreInfo() {
      this.infosLoadingMore = true
      // loading more info
      this.infosLoadingMore = false
    },
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    结语
    以上是简单的 Vue 页面触底加载组件的原理及实现,希望对你有所帮助,欢迎在评论区进行讨论或指正。

    监听事件函数部分参考了博客
    触底加载更多(原理 + 在vue中的使用)。

  • 相关阅读:
    Cholesterol-PEG-Amine,CLS-PEG-NH2,胆固醇-聚乙二醇-氨基脂两亲性脂质衍生物
    快速入门一篇搞定RocketMq-实现微服务实战落地
    【分享】获取微信通讯录python代码形式实现
    做进销存什么软件好用
    html常用标签
    大二Web课程设计——张家界旅游网站设计与实现(HTML+CSS+JavaScript)
    湘潭大学 2023年下学期《C语言》作业0x03-循环1 XTU OJ 1094,1095,1096,1112,1113
    【牛客网刷题】(第四弹)多道中等难度题,早日拿offer,快来看看
    第二证券|多只公募基金损失惨重;储能板块低开高走
    vue项目中订单完成提交按钮动画
  • 原文地址:https://blog.csdn.net/wenfu814/article/details/126838992