基于Vue实现上拉加载更多(方法+思路)

首先我们需要一个的大致结构差不多是这样的

<div class="load-more">
    <slot>这里的作用不多说</slot>
    <div class="load-state" v-if="showState">
      <div class="finish" v-if="finish">
        <span>加载完成</span>
      </div>
      <div class="more" v-else>
        <span>加载中</span>
      </div>
    </div>
</div>

分为一个大的div盒子,然后里面包含了父元素给的数据内容,底部一些自己加载的状态

我们要实现的功能:
1、页面进入自动去加载我们的数据,滑动到底部继续加载新的数据
2、当第一次数据加载完成但是数据不足一屏,继续实行加载方法,直到超过一屏停止
3、页面数据少,不足一屏且没有更多数据,不显示底部加载状态

我们在data里配置一些我们需要的参数

data () {
  return {
    loadState: true, // 是否显示底部加载状态,默认true
    finish: false, // 是否加载完成
    loading: false, // 是否正在加载中
    domHeight: 0, // 内容可视区的高度
    container: null // 绑定能被监听滚动的元素
  }
},

接下来我们在mounted里面写一些我们需要的内容:

mounted () {
    // 如果组件是基于body或者其他父元素进行滚动,则下面获取的对象为相应的对象
    this.container = this.$el
    this.domHeight = this.$el.clientHeight
    this.switchBottom()
    this.bindSrcoll()
}

上拉加载更多功能及什么时候加载等

scrollPage () {
  if (!this.$el) {
    return
  }
  // 获取内容向上滚动了多少距离
  var domScrollTop = this.container.scrollTop
  // 当内容滚动到距离底部<50时,且没有加载完成&&没有正在加载中
  // 内容距离底部多少距离 = 内容总高度-滚动高度-当前可视高度
  if (this.$el.scrollHeight - domScrollTop - this.domHeight < 50 && !this.loading && !this.finish) {
  // 设置为正在加载中
    this.loading = true
    // 0.5秒后执行父组件接口方法
    setTimeout(() => {
        this.$emit('loadMore')
    }, 500)
  }
},

到这里是不是大概明白加载更多实现方式了,现在来写上面实现功能的第二和第三点:

switchBottom () {
  this.$nextTick(() => {
    // 判断容器内容是否 大于 自身内容可视区域高度
    if (this.$el.scrollHeight > this.domHeight) {
        // 如果大于,则显示加载状态,至于是加载完成还是没有可以继续加载,我们不用关心,如果继续上滑有数据会执行方法的
        this.showState = true
    } else {
      // 如果页面不足一屏且还有下一页数据,继续执行加载更多方法
        if (!this.finish) {
            // 不足一屏,还有数据,现在加载状态
          this.showState = true
            // 执行父组件请求数据方法
          setTimeout(() => {
            this.$emit('loadMore')
          }, 1000)
      } else {
        // 没有数据不显示底部加载状态
        this.showState = false
      }
    }
  })
},

上面的switchBottom我们会在上面的mounted里面默认执行一次
但是如果只执行一次,那么如果遇到我们功能的第二点场景的时候,就不能实现我们要的效果了,所以我们需要在updated周期时候再执行,如果有用到缓存,也需要将方法写在activated一次

// 视图数据更新,重新调用
updated () {
    this.switchBottom()
},
// 如果有用到keep-alive,组件激活时调用
activated () {
  this.switchBottom()
},

最后我们需要将页面元素绑定一个滚动事件和移除滚动事件,滚动事件方法也需要在mounted里调用

bindSrcoll () {
  this.unScroll()
  if (this.scrollContainer) {
    this.container.addEventListener('scroll', this.scrollPage)
  }
},
unScroll () {
  if (this.scrollContainer) {
    this.container.removeEventListener('scroll', this.scrollPage)
  }
}

最后一点要注意,我们离开了当前路由,是需要将我们的滚动事件销毁的,不要会一直处于监听状态

// 页面销毁,移除滚动监听
beforeDestroy () {
    this.unScroll()
}

到此我们的加载更多方法基本完成;
值得注意的是,需要里面绑定滚动的元素是生效在什么地方,需要根据自己项目具体去写对应的样式,总之,能滚动的元素是有一个固定高度的,如果都没有,只能将滚动事件绑定到body上,将body的高度设置为100%,voerflow:auto即可

最后怎么使用,在父元素引入我们的组件
import LoadMore from '@/public/LoadMore/Index.vue'
在html片段写上
<LoadMore ref="LoadMore" @loadMore="onScrollBottom"></LoadMore>

conScrollBottom方法里面调用请求数据的方法

// 加载更多
onScrollBottom () {
    this.getData()
},

getData方法里面需要进行如下判断
数据请求成功后:

// 假如数据拿成功并渲染
if (result.code == 0) {
    this.list = this.list.concat(result.data.fileList)
    // 如果没有更多数据,则加载完成
    if (!result.data.nextPage) {
      this.$refs.LoadMore.finish = true
      return
    }
    // 关闭正在加载中
    if (this.$refs.LoadMore) {
        this.$refs.LoadMore.loading = false
    }
}

希望对你有帮助

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,448评论 25 707
  • 伫立在春天的植物 在傍晚的风中 互相依偎 行人们表情木然 低头看着脚下 默默数着岁月的呢喃 我在十字街口 没有碰到...
    李清澄阅读 270评论 0 1
  • 一、前言 可能大家在学习java的基础过程中,都知道StringBuilder相对StringBuffer效率更高...
    叫我宫城大人阅读 16,948评论 6 10
  • 因为很早离开家,所以对父母的依赖比较少。但能回家乡的时间总是尽一切可能回家。 时间花在哪里都是看得见的。 和他们在...
    旭珍阅读 225评论 0 0
  • 人与人之间是通过感受的表达来连接的。也就是:我有一种情绪,萦绕在心间。你看到了它,理解了它,我们之间就产生了连接。...
    木子青青草阅读 672评论 0 0