项目背景
在我的开源项目 homie 匹配(http://hm.hejiajun.icu/)的首页中就是利用的 vue-infinite-loading 组件实现的滑动加载,整体的引入和使用还是比较简单的,下面由我带大家快速上手吧。

快速上手
官网:Configure Load Messages | Vue-infinite-loading
1.安装依赖:
1
| npm install v3-infinite-loading
|
2.在 main.ts 或者要用到的文件中全局引入,我是在用到的
1
| import InfiniteLoading from "v3-infinite-loading";
|
3.引入组件:
1 2 3
| <div style="display: flex; justify-content: center;"> <infinite-loading :identifier="infiniteId" @infinite="loadMore" v-if="!isMatchMode"/> </div>
|
4.定义加载更多函数,目的是不断增加页数,通过 hasMoreData 来判断是否有更多数据,有就增加页数,当组件触发到页面底部是就会调用这个函数,然后你就可以添加分页的参数,以便查询下一页数据。
1 2 3 4 5 6
| const loadMore = () => { if (hasMoreData.value) { pageNum++; loadData(); } };
|
5.有人会问 hasMoreData 的作用是什么,它的作用主要是判断是否用更多的数据(布尔值),当滑动页面时前端会不断请求下一页的数据,如果后端返回前端的数据大于 0 就代表还有更多的数据那么值就为 true,否则就没有那么就为 false。因此可以通过这个参数来控制页数的是否需要增加,如果没有的话就会一直请求后端,会给服务器增加很多压力。
这个边我贴一下前端请求后端数据和后端返回数据的一个大致代码:
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
| userListData = await myAxios.get('/user/recommend', { params: { pageSize: 3, pageNum }, }).then(response => { console.log('/user/recommend succeed', response); return response?.data; }).catch(error => { console.log('/user/recommend error', error); }); if (userListData) { userListData.forEach((user: UserType) => { if (user.tags) { user.tags = JSON.parse(user.tags); } }); if (pageNum === 1) { userList.value = userListData; } else { userList.value = [...userList.value, ...userListData]; } hasMoreData.value = userListData.length > 0; } loading.value = false;
|
以下是整体代码,想深入研究或者没理解的可以看看整体的逻辑,如果引入时出现问题可以私信我。
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
| <template> <van-search v-model="searchText" placeholder="搜索附近用户" @search="onSearch(searchText)"/> <van-cell center title="心动模式"> <template #right-icon> <van-switch v-model="isMatchMode" size="24" @change="onMatchModeChange"/> </template> </van-cell> <user-card-list :user-list="userList" :loading="loading"/> <van-back-top right="15vw" bottom="10vh" /> <div style="display: flex; justify-content: center;"> <infinite-loading :identifier="infiniteId" @infinite="loadMore" v-if="!isMatchMode"/> </div> <van-empty v-if="!userList || userList.length < 1" description="数据为空"/> </template> <script setup lang="ts"> import {ref, watchEffect} from "vue"; import {useRoute} from "vue-router"; import myAxios from "../plugins/myAxios.ts"; import UserCardList from "../components/UserCardList.vue"; import {UserType} from "../models/user" import {showToast} from "vant"; import InfiniteLoading from "v3-infinite-loading"; const route = useRoute(); const {tags} = route.query; const searchText = ref(''); const userList = ref<UserType[]>([]); const isMatchMode = ref<boolean>(false); const loading = ref(true); const infiniteId = 'infinite-loading-id'; let pageNum = 1; let hasMoreData = ref(true); /** * 加载数据 */ const loadData = async () => { let userListData; loading.value = true; if (isMatchMode.value) { const num = 10; userListData = await myAxios.get('/user/match', { params: { num }, }).then(response => { console.log('/user/match succeed', response); return response?.data; }).catch(error => { console.log('/user/match error', error); }); if (userListData) { userListData.forEach((user: UserType) => { if (user.tags) { user.tags = JSON.parse(user.tags); } }); } userList.value = userListData || []; loading.value = false; hasMoreData.value = false; } else { userListData = await myAxios.get('/user/recommend', { params: { pageSize: 3, pageNum }, }).then(response => { console.log('/user/recommend succeed', response); return response?.data; }).catch(error => { console.log('/user/recommend error', error); }); if (userListData) { userListData.forEach((user: UserType) => { if (user.tags) { user.tags = JSON.parse(user.tags); } }); if (pageNum === 1) { userList.value = userListData; } else { userList.value = [...userList.value, ...userListData]; } hasMoreData.value = userListData.length > 0; } loading.value = false; } }; const onMatchModeChange = () => { userList.value = []; pageNum = 1; hasMoreData.value = true; loadData(); }; const loadMore = () => { if (hasMoreData.value) { pageNum++; loadData(); } }; const onSearch = async (searchText: string) => { let userListData; loading.value = true; const res = await myAxios.get('/user/searchNearby', { params: { radius: searchText } }); if (res?.code === 0) { userListData = res?.data; if (userListData) { userListData.forEach((user: UserType) => { if (user.tags) { user.tags = JSON.parse(user.tags); } }); userList.value = userListData; } loading.value = false; } else { showToast('搜索失败' + (res.description ? `,${res.description}` : '')); } loading.value = false; }; watchEffect(() => { loadData(); }); </script> <style scoped> </style>
|
效果
当我向下滑动时,是不是就会发送请求下一页数据的请求啊,当我拉到最下面时也就停止请求了,是吧?

我的开源项目
如果你对我的开源项目(http://hm.hejiajun.icu/)感兴趣的话,可以看看它的介绍 我终于有我的开源项目了!!!-CSDN博客 哦,后续我还会介绍这个项目的更多亮点和实现原理,如果有帮到你的话不放帮我点个关注,谢谢!