vue实现组件无限滚动

If you’ve ever caught yourself on social media for way too long, chances are the site you were on was using an infinite scrolling component.

如果您在社交媒体上陷入困境的时间过长,那么您所在的网站很可能正在使用无限滚动组件

An infinite scrolling component is when new content is loaded as the user scrolls down the page as opposed to separating it out into multiple pages.

无限滚动组件是在用户向下滚动页面时加载新内容的过程,而不是将其分为多个页面。

They are highly effective for specific types of content such as user-generated content.

它们对于特定类型的内容(例如用户生成的内容)非常有效。

Here’s an example of what infinite scrolling is.

这是无限滚动的示例。

Image for post
https://addyosmani.com https://addyosmani.com

In this tutorial, we’ll be creating a Vue3 Infinite Scrolling Component using the Composition API. Here’s a sneak peek of what we’ll be building by the end of it. As you can see, it scrolls indefinitely and the scrollbar on the right side of the screen reflects this.

在本教程中,我们将使用Composition API创建一个Vue3无限滚动组件。 这是我们到最后将要构建的内容的预览。 如您所见,它会无限滚动,并且屏幕右侧的滚动条会反映出这一点。

Image for post

Live Demo

现场演示

Okay — let’s jump right in.

好的-让我们直接进入。

为什么还要使用无限滚动组件? (Why even use Infinite Scrolling Component?)

We’ve all seen examples of websites that use infinite scrolling to display their content, but when would this be a better option than using a typical pagination system?

我们都看到过使用无限滚动来显示其内容的网站的示例,但是与使用典型的分页系统相比,这将是一个更好的选择吗?

There’s a great article by Nick Babich on the pros and cons of infinite scrolling/pagination. I definitely recommend giving it a read, but I’ll sum up the main points.

尼克·巴比奇(Nick Babich)有一篇很棒的文章,介绍了无限滚动/分页的利弊 。 我绝对建议您阅读它,但我将总结要点。

Pros of Infinite Scrolling:

无限滚动的优点:

  • User Engagement and Content Discovery

    用户参与和内容发现
  • Scrolling is Better Than Clicking (better usability)

    滚动胜于点击(可用性更高)
  • Scrolling is Good For Mobile Devices

    滚动对移动设备有利

Cons of Infinite Scrolling:

无限滚动的缺点:

  • Page Performance and Device Resources

    页面性能和设备资源
  • Item Search and Location — users can’t bookmark a page and retain position

    项目搜索和位置-用户无法为页面添加书签并保留位置
  • Irrelevant Scroll Bar

    不相关的滚动条

Like all things with web development, there are valid reasons for choosing either option. Just be sure to consider which is best for your website!

像Web开发中的所有事物一样,有充分的理由选择这两个选项。 只要确保考虑最适合您的网站!

Regardless, learning how to build a Vue3 infinite scrolling component is pretty interesting and could be useful for you down the line.

无论如何,学习如何构建Vue3无限滚动组件都很有趣,并且可能对您很有用。

好的。 让我们做吧。 (Okay. Let’s make it.)

First, let’s go over — from a high level — how this system will work.

首先,让我们从更高的层次来回顾一下该系统的工作方式。

There are going to be three main parts:

将包括三个主要部分:

  1. A Mock API call that generates posts

    生成帖子的Mock API调用
  2. PostComponent that renders an individual post

    呈现单个帖子的PostComponent
  3. ListComponent that contains all the post components and handles loading posts from the API

    ListComponent包含所有发布组件,并处理从API加载的发布

模拟API调用 (Mocking an API Call)

For this tutorial, we’ll be writing a dummy API call that returns hard coded data. If you implement this in a real backend and database, the important aspects are that you can decide somehow limit your results based on size and position in the database.

在本教程中,我们将编写一个虚拟API调用,以返回硬编码数据。 如果在真实的后端和数据库中实现此功能,则重要的方面是可以基于数据库的大小和位置来决定以某种方式限制结果。

This API call can be anything from a simple database query in simpler applications all the way to a complex recommendation algorithm in more advanced ones.

这个API调用可以是任何东西,从简单应用程序中的简单数据库查询一直到高级应用程序中的复杂推荐算法。

Here are some different ideas for content loading algorithms that are used commonly by social media sites:

这是社交媒体网站常用的内容加载算法的一些不同想法:

  • Date posted

    发布日期
  • Relevance to the current user

    与当前用户的相关性
  • Activity on a post

    帖子中的活动

However, for simplicity, our algorithm will just generate random post data and return X number of posts depending on the parameters it’s given.

但是,为简单起见,我们的算法将只生成随机的帖子数据,并根据给定的参数返回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

制作我们的帖子组件 (Making our post component)

Now that we have a way to generate posts, let’s create a component that will allow us to render them.

现在我们有了生成帖子的方法,让我们创建一个允许我们渲染它们的组件。

There’s not anything fancy about this code, we just have to take in a post via the component’s props and then render the author and content. There are also a few styles here to pretty things up a little bit.

这段代码没有什么花哨的,我们只需要通过组件的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>

显示我们的帖子 (Displaying our posts)

Next, let’s actually figure out how to display some posts on the screen. And this is where that ListComponent.vue component comes in handy.

接下来,让我们实际弄清楚如何在屏幕上显示一些帖子。 这就是ListComponent.vue组件派上用场的地方。

If you don’t have any experience in Vue3, this code may look a little weird to you. But check out this guide to getting started in Vue3.

如果您没有使用Vue3的经验,那么这段代码对您可能会有些奇怪。 但是请查看本Vue3入门指南

In short, Vue3 replaces the Options API with the Composition API meaning that the code (lifecycle hooks, data, etc) is all organized inside a single setup method.

简而言之,Vue3用Composition API替换了Options API,这意味着代码( 生命周期挂钩 ,数据等)全部都在一个setup方法中进行组织。

So first, we want to import a few things:

因此,首先,我们要导入一些内容:

  • Our API call

    我们的API调用
  • Our PostComponent

    我们的PostComponent
  • ref for creating reactive data

    ref创建React数据

  • onMounted and onUnmounted to access these lifecycle hooks

    onMountedonUnmounted访问这些生命周期挂钩

import PostComponent from './PostComponent.vue'
import { ref, onMounted, onUnmounted } from 'vue'
import getPosts from '../scripts/post-loader'

Next, inside our setup method — we want to set up a reactive posts variable that calls our getPosts API call. Don't forget to return it so that our template can access it!

接下来,在我们的setup方法中-我们想要设置一个React式的post变量,该变量调用我们的getPosts API调用。 不要忘记返回它,以便我们的模板可以访问它!

setup () {
const posts = ref(getPosts(10))
return {
posts,
}
}

Finally, to display our data inside our template, we want to run a v-for loop that iterates over our posts and renders a PostComponent for each of them. Our template should look like this (note that the .list-component has a ref, we'll get to that later)

最后,要在模板中显示数据,我们想运行一个v-for循环,该循环遍历我们的帖子并为每个帖子渲染一个PostComponent。 我们的模板应如下所示(请注意, .list-component具有引用,我们将在稍后进行介绍)

<template>
<div class='scrolling-component' ref='scrollComponent'>
<post-component v-for='post in posts' :post="post" />
</div>
</template>
<script>

Our current page should render 10 posts and look like this.

我们当前的页面应呈现10个帖子,如下所示。

But if we scroll to the bottom, nothing happens. So let’s move on to the exciting part: infinite scrolling!

但是,如果我们滚动到底部,则什么也不会发生。 因此,让我们继续进行令人兴奋的部分:无限滚动!

处理Vue3无限滚动 (Handling Vue3 Infinite Scrolling)

Now that we have everything set up, we can start loading in more data as the user scrolls down to the bottom of the posts.

现在我们已经完成了所有设置,随着用户向下滚动到帖子底部,我们可以开始加载更多数据。

Let’s start off by creating a method that loads in 10 posts at a time and appends them to our posts variable.

让我们开始创建一个方法,该方法一次加载10个帖子,并将它们附加到我们的posts变量中。

setup () {
// ...
const loadMorePosts = () => {
let newPosts = getPosts(10)
console.log(newPosts)
posts.value.push(...newPosts)
}
// ...
}

Now, we just need a way to trigger this method. We are going to do this by adding an event listener that listens to a scroll event and calls a method. We are going to add it when the component is mounted and remove it when the component is unmounted (destroyed).

现在,我们只需要一种触发该方法的方法即可。 为此,我们将添加一个事件侦听器,该侦听器侦听滚动事件并调用一个方法。 我们将在安装组件时添加它,并在卸载(销毁)组件时将其删除。

setup () {
// ...
onMounted(() => {
window.addEventListener("scroll", handleScroll)
})
onUnmounted(() => {
window.removeEventListener("scroll", handleScroll)
})
const handleScroll = (e) => {
}
// ...
}

Great. We’re all set up to start loading in more posts. If you remember from the previous section, we added a refs attribute to the .list-component element. If you've worked with refs in Vue before, this is a familiar concept, but the way we set them up in Vue3 is a little different.

大。 我们都已经准备好开始加载更多帖子。 如果您还记得上一节的内容,我们向.list-component元素添加了一个refs属性。 如果您以前在Vue中使用过引用,这是一个熟悉的概念,但是我们在Vue3中进行设置的方式有所不同。

We are going to use the refs method again to instantiate our ref and then return it from our setup method.

我们将再次使用refs方法来实例化ref,然后从我们的setup方法中将其返回。

setup () {
const posts = ref(getPosts(10))
const scrollComponent = ref(null)
return {
posts,
scrollComponent
}
}

With this access to our element using refs, we can finish up our method to determine if we are scrolled to the bottom of our content.

通过使用refs对元素的访问,我们可以完成我们的方法以确定是否滚动到内容的底部。

The following code works by checking if the bottom of our content is visible on the screen. If it is, we call our method to load in more posts!

以下代码通过检查内容的底部是否在屏幕上可见来工作。 如果是这样,我们调用我们的方法以加载更多帖子!

const handleScroll = (e) => {
let element = scrollComponent.value
if ( element.getBoundingClientRect().bottom < window.innerHeight ) {
loadMorePosts()
}
}

And that’s it! When we scroll down to the bottom of our current posts, new posts should automatically load in. Let’s take a look at what we have.

就是这样! 当我们向下滚动到当前帖子的底部时,新帖子将自动加载。让我们看一下我们拥有的内容。

Perfect!

完善!

我们无限滚动组件的可能扩展 (Possible Extensions to our Infinite Scrolling Component)

This is just an introduction to creating a Vue3 infinite scrolling component. There are so many different directions to take this to improve it.

这只是创建Vue3无限滚动组件的介绍。 有很多不同的方向可以用来改进它。

Here are some ideas that I would think about adding if you’re building this in a real system.

如果您是在实际系统中构建的,请考虑以下一些想法。

  • Since the API call would be asynchronous, create some sort of loading spinner that displays while new data is being loaded

    由于API调用将是异步的,因此请创建某种加载微调器 ,以在加载新数据时显示

  • Create a more complex API algorithm and connect it to a database

    创建更复杂的API算法并将其连接到数据库
  • Add more data to each post and find new ways to display it

    向每个帖子添加更多数据,并找到新的显示方式

结论 (Conclusion)

And there you have it! I hope this tutorial was helpful to both get you acclimated in Vue3 as well as create a pretty cool component.

在那里,您拥有了! 我希望本教程对您熟悉Vue3以及创建一个很棒的组件很有帮助。

Here’s a link to the final Github repo if you want to see it for yourself.

如果您想亲自观看, 这里是最终Github存储库的链接

If you build this/add any extensions, I would love to see what you make! To show off your projects or if you have any questions, just leave a reply.

如果您构建了这个/添加了任何扩展,我很乐意看到您所做的! 要炫耀您的项目或有任何疑问,请留下答复。

Happy coding!

编码愉快!

If you’re interested in learning more about VueJS click here to get a free Vue cheatsheet with all the essential code snippets for developers and click here to access our Vue3 Build Along Course.

如果您想了解有关VueJS的更多信息,请单击此处以获取免费的Vue速查表,其中包含针对开发人员的所有基本代码段 ,然后单击此处以访问我们的Vue3 Build With Course。

翻译自: https://medium.com/javascript-in-plain-english/a-quick-vue3-infinite-scrolling-component-daily-vue-tips-4-20c7052ccda4

vue实现组件无限滚动

Logo

前往低代码交流专区

更多推荐