赞
踩
在移动应用开发中,无限滚动加载是一个常见的功能,用户可以通过滑动屏幕来加载更多的内容,从而提高应用的用户体验。本文将介绍如何使用Uniapp实现无限滚动加载的功能。
我们需要实现的无限滚动加载功能的具体效果如下:
当用户滑动到底部时,自动加载更多的数据。
在加载数据时,显示一个加载动画,防止用户误以为应用已经崩溃。
当所有数据都已经加载完毕时,提示用户“没有更多数据了”。
我们可以通过以下步骤来实现无限滚动加载功能:
在cs.vue
组件中,使用uni.createIntersectionObserver()
方法创建一个交叉观察器,用于观察加载动画是否进入了用户的视图区域。
在交叉观察器的回调函数中,判断加载动画是否进入了用户的视图区域,并根据需要加载更多的数据。
在加载数据时,使用事件来控制加载动画的出现与隐藏。
当所有数据都已经加载完毕时,使用事件来控制“没有更多数据了”的提示是否显示。
在index.vue
组件中,引入cs.vue
组件,并通过事件来控制加载动画和“没有更多数据了”的提示是否显示。
在cs.vue
组件中,我们需要使用事件来控制加载动画的出现与隐藏。具体来说,当交叉观察器的回调函数中判断需要加载数据时,我们需要通过$emit
方法触发一个名为aaa
的事件,并传递参数0,表示加载动画需要出现。当数据加载完毕后,我们再次触发aaa
事件,并传递参数1,表示加载动画需要消失。代码如下:
- if (res.intersectionRatio > 0) {
- this.$emit("aaa", 0); // 加载动画出现
- setTimeout(() => {
- this.a += 10;
- this.$emit("aaa", 1); // 加载动画消失
- }, 3000)
- }
在cs.vue
组件中,我们还需要使用事件来控制“没有更多数据了”的提示是否显示。具体来说,当所有数据都已经加载完毕时,我们需要通过$emit
方法触发一个名为aaa
的事件,并传递参数2,表示“没有更多数据了”的提示需要显示。代码如下:
if (this.a > 50) return this.$emit("aaa", 2);
在index.vue
组件中,我们需要引入cs.vue
组件,并通过事件来控制加载动画和“没有更多数据了”的提示是否显示。具体来说,我们需要监听aaa
事件,并根据传递的参数来控制加载动画和“没有更多数据了”的提示是否显示。代码如下:
- <template>
- <view class="container">
- <text>{{appear === 0 ? '小球出现' : '小球消失'}}</text>{{appear}}
- <view class="page-section">
- <scroll-view class="scroll-view" scroll-y>
- <cs :appear="appear" @aaa="(val) => appear=val"></cs>
- </scroll-view>
- </view>
- </view>
- </template>
-
- <script>
- import cs from './cs.vue';
- let observer = null;
- export default {
- components: {
- cs
- },
- data() {
- return {
- appear: 1
- }
- },
-
- }
- </script>
最后,为了避免内存泄漏,我们需要在cs.vue
组件销毁时将交叉观察器断开连接。具体来说,我们需要在onUnload
生命周期函数中使用disconnect()
方法将交叉观察器断开连接。代码如下:
- onUnload() {
- if (observer) {
- observer.disconnect()
- }
- }
至此,我们就完成了无限滚动加载的实现。完整代码如下:
cs.vue
组件代码:
- <template>
- <view>
- <view class="item" v-for="item of a" :key="item">
- {{item}}锄禾日当午
- </view>
- <qiuy-loading class="ball" :class="{'is':appear===0}"></qiuy-loading>
- <view v-show="appear===2">
- 没有数据了
- </view>
- </view>
- </template>
-
- <script>
- let observer = null;
- import QiuyLoading from './QiuyLoading.vue'
- export default {
- components: {
- QiuyLoading
- },
- props: ["appear"],
- data() {
- return {
- a: 20
- }
- },
- mounted() {
- observer = uni.createIntersectionObserver(this);
- observer.relativeTo('.scroll-view').observe('.ball', (res) => {
-
- // 当a》50时,停止加载
- if (this.a > 50) return this.$emit("aaa", 2);
- // 如果当前状态已经在加载中,则不进行。
- if (this.appear !== 1) return;
- // 出现了
- if (res.intersectionRatio > 60) {
- // 先让加载动画显示出来
- this.$emit("aaa", 0);
- setTimeout(() => {
- this.a += 10;
- // 加载出了数据,关闭加载动画
- this.$emit("aaa", 1);
- }, 3000)
- }
- })
- },
- onUnload() {
- if (observer) {
- observer.disconnect()
- }
- }
- }
- </script>
-
- <style>
- .notice {
- margin-top: 150rpx;
- margin: 150rpx 0 400rpx 0;
- }
-
- .is {
- height: auto;
- overflow: hidden;
- }
-
- .item {
- line-height: 100rpx;
- font-size: 40rpx;
- }
- </style>
index.vue
组件代码:
- <template>
- <view class="container">
- <text>{{appear === 0 ? '小球出现' : '小球消失'}}</text>{{appear}}
- <view class="page-section">
- <scroll-view class="scroll-view" scroll-y>
- <cs :appear="appear" @aaa="(val) => appear=val"></cs>
- </scroll-view>
- </view>
-
- </view>
- </template>
- <script>
- import cs from './cs.vue';
- let observer = null;
- export default {
- components: {
- cs
- },
- data() {
- return {
- appear: 1
- }
- },
- }
- </script>
- <style>
- .scroll-view {
- height: 800rpx;
- background: #fff;
- border: 1px solid #ccc;
- box-sizing: border-box;
- /* padding-bottom: 30px; */
- }
-
- .scroll-area {
- height: 1300rpx;
- display: flex;
- flex-direction: column;
- align-items: center;
- transition: .5s;
- }
- </style>
QiuyLoading.vue里的内容
- <template>
- <view class="loader">
- <view class="l">L</view>
- <view class="o">o</view>
- <view class="a">a</view>
- <view class="d">d</view>
- <view class="i">i</view>
- <view class="n">n</view>
- <view class="g">g</view>
- <view class="d1">.</view>
- <view class="d2">.</view>
- </view>
- </template>
-
- <script>
- </script>
-
- <style>
- .loader {
- text-align: center;
- height: 0;
- overflow: hidden;
- }
-
- .is {
- height: auto;
- padding-bottom: 20rpx;
- }
- </style>
最后,看下效果吧!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。