【下拉刷新 + 触底加载 】使用的是uni-app自带的 scroll-view 组件
文档地址 : https://uniapp.dcloud.io/component/scroll-view?id=scroll-view

scroll-view 需要使用到的几个api :

api 属性名 说明
scroll-y 允许纵向滚动
refresher-enabled 开启自定义下拉刷新
refresher-triggered 设置当前下拉刷新状态,true 表示下拉刷新已经被触发,false 表示下拉刷新未被触发
@refresherrefresh 自定义下拉刷新被触发
@scrolltolower 滚动到底部/右边,会触发 scrolltolower 事件
refresher-background 设置自定义下拉刷新区域背景颜色

注意事项:

使用竖向滚动时,需要给 一个固定高度,通过 css 设置 height。

【触底加载】 这里需要配合使用 uView 的 loadMore 组件
文档地址 : https://www.uviewui.com/components/loadMore.html

loadMore 需要使用到的api :

api 属性名 说明 可选值
status 组件状态 加载前值为 loadmore
加载中值为 loading
没有数据为 nomore

页面交互判断逻辑:

  1. 下拉刷新

触发拉下刷新的回调函数 @refresherrefresh 在这个函数中,要做的几个动作 :
配置刷新状态 refresher-triggered = true -> await 重新加载数据 -> refresher-triggered = false

  1. 触底加载的动作:
    通过数据总条数 和 当前数据条数,配置 u-loadmore 的 status 控制底部显示文字

@scrolltolower 回调 触发 加载更多数据

code 如下

  1. <template>
  2. <view class="meetingContent">
  3. <scroll-view scroll-y="true" refresher-enabled @refresherrefresh="onRefresh"
  4. refresher-background="rgba(244, 246, 248, 1)" :refresher-triggered="triggered" @scrolltolower="scrolltolower">
  5. <u-empty v-if="!loading && total === 0" />
  6. <template v-else>
  7. <view v-for="item in meetingList" :key="item.id">
  8. <u-gap height="20" bg-color="rgba(244, 246, 248, 1)" />
  9. <meeting-card :info="item"></meeting-card>
  10. </view>
  11. <u-loadmore :status="loadMoreStatus" />
  12. </template>
  13. </scroll-view>
  14. </view>
  15. </template>
  16. <script>
  17. // MeetingCard 是UI组件,这里可以随便替换成自己的demo结构
  18. import MeetingCard from '../components/meetingCard.vue';
  19. export default {
  20. data: () => ({
  21. loading: true, // 暂无数据 flag
  22. total: 0,
  23. loadMoreStatus: "loadmore",
  24. reloadStatus: false, // 数据重新加载 flag
  25. triggered: false, // 下拉状态
  26. current: 1,
  27. meetingList: [],
  28. }),
  29. methods: {
  30. fetchCardListData() { // 获取界面数据
  31. console.log('this.fetchCardListData -- params',this.searchParams)
  32. console.log('获取页面数据呢')
  33. this.loading = true;
  34. const resData = [{
  35. id: '1zxd',
  36. status: 1,
  37. checkTime: 1624772266174,
  38. createName: '王伟',
  39. meetingName: '【监理例会】会议纪要20210509',
  40. meetingOrg: '重庆十八梯项目',
  41. riskKey: '劳动力不足,机械不足,材料不足',
  42. riskType: '质量、安全、人员履职、环境'
  43. }, {
  44. id: 'sdfsafd',
  45. status: 2,
  46. checkTime: 1624772266174,
  47. createName: '王伟',
  48. meetingName: '【监理例会】会议纪要20210509',
  49. meetingOrg: '重庆十八梯项目',
  50. riskKey: '劳动力不足,机械不足,材料不足',
  51. riskType: '质量、安全、人员履职、环境'
  52. }]
  53. // 判断是下拉刷新 还是 触底更多
  54. if(this.reloadStatus){
  55. this.meetingList = resData
  56. }else{
  57. this.meetingList = this.meetingList.concat(resData);
  58. }
  59. this.loading = false;
  60. this.total = 3;
  61. // 判断是否可以触底加载
  62. this.meetingList.length < this.total ? this.loadMoreStatus = 'loadmore' : this.loadMoreStatus = "nomore";
  63. this.reloadStatus = false;
  64. this.loading = false;
  65. },
  66. reloadData() { // 重新加载数据 fn
  67. this.current = 1;
  68. this.reloadStatus = true;
  69. this.meetingList = [];
  70. return this.fetchCardListData();
  71. },
  72. async onRefresh() { // 下拉刷新被触发
  73. console.log('下拉触发')
  74. this.triggered = true;
  75. await this.reloadData();
  76. this.triggered = false;
  77. },
  78. scrolltolower() { // 滚动到最底部 触底加载
  79. console.log('触底加载')
  80. if (this.meetingList.length < this.total) {
  81. this.loadMoreStatus = "loading";
  82. this.current++;
  83. this.fetchCardListData();
  84. } else {
  85. this.loadMoreStatus = "nomore";
  86. }
  87. }
  88. }
  89. }
  90. </script>
  91. <style lang="scss" scoped>
  92. .meeting_wrap{
  93. height: 100%;
  94. }
  95. .meetingContent {
  96. flex: auto;
  97. overflow: hidden;
  98. height:900rpx;
  99. }
  100. scroll-view {
  101. height: 100%;
  102. }
  103. </style>

运行效果:
初始化 ->
image.png

下拉 :
image.png
image.png

触底:
image.png