如果你在社交媒体上停留的时间过长,那么,你所在的网站很可能正在使用无限滚动组件。
无限滚动组件是在用户向下滚动页面时加载新内容,而不是将其分成多个页面。
它们对于特定类型的内容(例如用户生成的内容)非常有效。
以下是无限滚动的示例。
在今天的教程中,我们将使用 Composition API 创建一个 Vue3 无限滚动组件。这是我们将在它结束时构建的内容的预览。
如你所见,它是无限滚动,屏幕右侧的滚动条反映了这一点。
现在,让我们一起来看看这个组件的实现过程。
为什么还要使用无限滚动组件?
我们都见过使用无限滚动来显示其内容的网站的示例,但是什么时候使用它,它的效果会比使用典型的分页系统更好呢?
你可以阅读我之前分享的一篇文章《无限滚动与分页哪个用户体验更好?如何正确使用它们》,在这里,我只简单的总结一下它们的有缺点。
无限滚动的优点:
- 用户参与和内容发现
- 滚动比点击更好(更好的可用性)
- 滚动适用于移动设备
无限滚动的缺点:
- 页面性能和设备资源
- 项目搜索和位置 - 用户无法为页面添加书签并保留位置
- 不相关的滚动条
就像所有与 Web 开发有关的事情一样,选择任何一个选项都有正当的理由。请务必考虑哪个最适合你的项目!
无论如何,学习如何构建一个 Vue3 无限滚动组件是非常有趣的,并且可能对你有用。
首先,让我们从高层次上回顾一下这个系统是如何工作的。
主要分为三个部分:
- 生成内容的模拟 API 调用
- 呈现单个内容的 PostComponent
- ListComponent 包含所有内容组件并处理从 API 加载内容
1.模拟 API 调用
在教程中,我们将编写一个返回硬编码数据的虚拟 API 调用。如果你在真实的后端和数据库中实现这一点,重要的方面,你可以根据数据库中的大小和位置决定以某种方式限制你的结果。
这个 API 调用可以是任何东西,从简单应用程序中的简单数据库查询一直到更高级应用程序中的复杂推荐算法。
以下是社交媒体网站常用的内容加载算法的一些不同想法:
- 发布日期
- 与当前用户的相关性
- 帖子上的活动
然而,为简单起见,我们的算法只会生成随机的帖子数据,并根据给定的参数返回 X 个帖子。
var names = ['Matt Maribojoc', 'Lebron James', 'Bill Gates', 'Childish Gambino'] // used to generate posts for this tutorial
const getPosts = (number) => {
// generate a number of posts
// in a real setting, this would be a database call or algorithm
let ret = []
for (var i = 0; i < number; i++) {
ret.push({
author: names[i % names.length],
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do.'
})
}
return ret
}
export default getPosts
2.制作我们的内容组件
现在我们有了生成内容的方法,让我们创建一个允许我们渲染它们的组件。
这段代码没有什么花哨的,我们只需要通过组件的 props 接收一个帖子,然后渲染作者和内容。这里也有一些风格可以让事情变得更漂亮。
<template>
<div class='post'>
<h2> {{ post.author }} </h2>
<p> {{ post.content }} </p>
</div>
</template>
<script>
export default {
props: {
post: Object
}
}
</script>
<style scoped>
.post {
background: #fff;
padding: 1.5em;
}
.post:not(:last-child) {
border-bottom: 1px solid #ddd;
}
.post h2 {
font-size: 1.3em;
padding-bottom: 0.25rem;
}
.post p {
color: #888;
}
</style>
3.显示我们的内容
接下来,让我们实际弄清楚如何在屏幕上显示一些帖子。这就是 ListComponent.vue 组件派上用场的地方。
如果你没有任何 Vue3 经验,这段代码对你来说可能有点奇怪。但是请查看本 Vue3 入门指南。
简而言之,Vue3 将 Options API 替换为 Composition API,这意味着代码(生命周期挂钩、数据等)都组织在一个设置方法中。
所以首先,我们要导入一些东西:
- 我们的 API 调用
- 我们的 PostComponent
- 用于创建反应数据的参考
onMounted 和 onUnmounted 访问这些生命周期 hooks。
import PostComponent from './PostComponent.vue'
import { ref, onMounted, onUnmounted } from 'vue'
import getPosts from '../scripts/post-loader'
接下来,在我们的 setup 方法中,我们想要设置一个响应式的内容变量来调用我们的 getPosts API 调用。不要忘记返回它,以便我们的模板可以访问它!
setup () {
const posts = ref(getPosts(10))
return {
posts,
}
}
最后,为了在模板中显示我们的数据,我们想要运行一个 v-for 循环来迭代我们的内容并为每个内容呈现一个 PostComponent。我们的模板应该是这样的(注意 .list-component 有一个 ref,我们稍后会谈到)
<template>
<div class='scrolling-component' ref='scrollComponent'>
<post-component v-for='post in posts' :post="post" />
</div>
</template>
<script>
我们当前的页面应该呈现 10 个内容,但是如果我们滚动到底部,什么都不会发生。
那么,现在让我们继续进行激动人心的部分:无限滚动!
4.Vue3 无限滚动
现在我们已经完成了所有设置,当用户向下滚动到内容底部时,我们可以开始加载更多数据。
让我们从创建一个方法开始,它一次加载 10 个内容并将它们附加到我们的帖子变量中。
setup () {
// ...
const loadMorePosts = () => {
let newPosts = getPosts(10)
console.log(newPosts)
posts.value.push(newPosts)
}
// ...
}
现在,我们只需要一种方法来触发这个方法。我们将通过添加一个监听滚动事件并调用方法的事件监听器来做到这一点。我们将在组件安装时添加它,并在组件卸载(销毁)时删除它。
setup () {
// ...
onMounted(() => {
window.addEventListener("scroll", handleScroll)
})
onUnmounted(() => {
window.removeEventListener("scroll", handleScroll)
})
const handleScroll = (e) => {
}
// ...
}
非常棒!现在,我们需要准备好开始加载更多内容了。如果你还记得前面的教程内容的话,其实,我们只需要向 .list-component 元素添加了一个 refs 属性。如果你之前在 Vue 中使用过 refs,这是一个熟悉的概念,但我们在 Vue3 中设置它们的方式有点不同。
我们将再次使用 refs 方法来实例化我们的 ref,然后,从我们的 setup 方法中返回它。
setup () {
const posts = ref(getPosts(10))
const scrollComponent = ref(null)
return {
posts,
scrollComponent
}
}
通过使用 refs 访问我们的元素,我们可以完成我们的方法来确定我们是否滚动到内容的底部。
以下代码通过检查我们内容的底部是否在屏幕上可见来工作。如果是,我们调用我们的方法来加载更多内容!
const handleScroll = (e) => {
let element = scrollComponent.value
if ( element.getBoundingClientRect().bottom < window.innerHeight ) {
loadMorePosts()
}
}
就是这样!当我们向下滚动到当前内容的底部时,应该会自动加载新内容。让我们看看我们有什么。
无限滚动组件的可能扩展
这只是创建Vue3无限滚动组件的介绍。有很多不同的方向可以改进它。
如果你在真实系统中构建它,我会考虑添加以下一些想法。
- 由于 API 调用将是异步的,因此创建某种加载微调器,在加载新数据时显示
- 创建更复杂的 API 算法并将其连接到数据库
- 为每个内容添加更多数据并找到显示它的新方法