在本教程中,我们将学习如何在无限滚动的情况下以块的形式获取和呈现数据,以及如何集成和使用 meilisearch 插件来搜索书籍。

作者: ** Taminoturoko Briggs**

一次获取大量数据可能会导致一些负面影响,例如使组件渲染缓慢,从而给网站访问者带来糟糕的用户体验。为了解决这个问题,常用的两种模式是无限滚动,我们将在本教程中介绍。

目标

在本教程中,我们将使用 Strapi 构建一个图书应用程序。该应用程序将专注于如何以无限滚动的方式获取和呈现数据块,以及如何集成和使用 meilisearch 插件来搜索书籍。

先决条件

要学习本教程,您应该熟悉 React,并且应该在系统中安装 Node。

Strapi 简介

Strapi 是一个开源、无头的内容管理系统 (CMS)使用 Nodejs Javascript 框架开发,允许快速设计 API 并且可以从任何客户端(React、Vue 等)访问,让开发人员可以自由使用他们的原生工具。

Strapi 包括一个用户友好的管理页面,该页面提供了易于管理和监控内容的功能。可以根据其插件系统自定义管理页面以及创建的 API,以匹配我们的用例,这是 Strapi 的可爱功能之一。

建立一个Strapi项目

设置 Strapi 项目非常简单。就像create-react-app一样,Strapi 也有zwz100024 create-strapi-app zwz100025 zwz100023

运行以下命令:

$ mkdir 图书应用程序

$ cd book-app

$ npx create-strapi-app@latest book-app-backend --quickstart

上面的命令为我们的应用程序设置了所有必需的依赖项的 Strapi,并创建了一个新文件夹book-app-backend

安装完成后,服务器将启动,我们可以通过指定的链接在浏览器中查看。在我们的浏览器中,我们如下页面:

截图

在这里,填写所需的详细信息并创建一个用户帐户以访问仪表板。

截图

创建集合类型

在集合类型中,我们将定义我们希望存储在 Strapi 上的内容。为此,首先,单击 Create your first Collection Type 按钮。

截图

在这个页面上,点击 Create new collection type ,我们会看到一个提示要求输入 Display name 和其他信息:

示例截图

输入 Books 作为显示名称,然后单击 Continue。 在下一个提示中,我们将看到可以为我们的收藏创建的不同字段类型。

示例截图

在这里,我们将为书籍创建字段。每本书都有作者、描述、图片、previewLink、publishDate、出版商、副标题和标题。这些是我们的书籍收藏类型将包括的字段。除了 authors 将是 JSON 类型之外,所有字段都将是文本字段。

示例截图

以上是图书数据的所有字段。创建完成后,点击页面右上角的保存按钮。

构建图书应用

图书应用程序将有一个主页,其中将显示我们的 Strapi 收藏中的所有可用图书,我们将使用无限滚动以块的形式获取这些图书。我们将有一个详细页面来显示有关特定书籍的信息,以及一个显示从 Meilisearch 收到的搜索结果的搜索页面。

我已经为 book 应用程序创建了一个 stater 存储库,其中包含我们将使用的模板和要添加的 Strapi 图书数据,我从Google book API获取。

接下来,我们需要克隆初始 GitHub 存储库。在终端中,cd 进入我们之前创建的 book-app 目录,然后输入以下代码行:

$ git clone -b starter https://github.com/Tammibriggs/strapi-book-app.git

$ cd 带书应用程序

$ npm 安装

现在,当我们使用$ npm start命令启动我们的应用程序时,我们将看到这个页面:

截图

如果我们单击一本书,我们将被带到如下所示的详细信息页面:

截图

现在,我们正在从克隆应用程序的 src 目录中的 data.js 文件中获取图书数据。我们将把图书数据移动到 Strapi 并很快使用 meilisearch 从那里获取它,并使用Intersection Observer API实现无限滚动。

向 Strapi 添加数据

src 目录下的 data.js 文件中,我们有超过五十四 (54) 个图书数据;让我们把它们移到 Strapi。为此,我们需要首先允许访问 Strapi 集合。导航到边栏的设置中的仪表板。在用户和权限下选择角色。点击 Public,选择 Book, 并选中所有复选框。

截图

然后,单击右上角的 Save 按钮以保存这些更改。

接下来,在 src/pages/Home.js 添加以下导入:

从'axios'导入axios

我们可以在此处导入 axios,因为它已包含在入门应用程序中。接下来,在Home组件中的books状态后添加如下代码行:

// src/pages/Home.js

常量 URL u003d "http://localhost:1337/api/books"

使用效果(()u003d> {

发送数据()

}, [])

常量 sendData u003d async () u003d> {

让 fetchedData;

const fetchCol u003d 等待 axios.get(URL)

fetchedData u003d fetchCol.data.data

如果(!fetchedData.length){

console.log('完成')

尝试 {

book.forEach((book) u003d> {

axios.post(网址,{

数据: {

作者:book.authors,

描述:book.description,

图片:book.image,

预览链接:book.previewLink,

发布日期:book.publishDate,

出版商:book.publisher,

副标题:book.subtitle,

书名:书名,

}})

})

console.log('完成')

} 捕捉(错误){

控制台日志(错误);

}

} 别的 {

console.log("数据已经上传")

}

}

上面的代码检查我们的 Strapi 集合中是否有任何数据,如果没有,它将使用 data.js 文件中的所有数据填充我们的集合。

现在,当我们前往 Strapi 仪表板并单击边栏中的 Content Manager 时,我们会在 Books 集合中看到五十四 (54) 个条目。

截图

接下来,我们将集成和使用 meilisearch 从我们的 Strapi 收藏中获取我们的书籍数据并显示它,并且还将实现搜索功能。为了搜索数据,meilisearch 使用传递给它的查询。当查询为空时,它将返回我们收藏中的所有书籍,我们将显示在主页上,当查询不为空时,它将返回相应的结果。

集成美利搜索

要在本地使用 Meilisearch,我们将下载并运行它的一个实例。这个可以在这里下载。打开下载的应用程序会显示一个终端,该终端具有托管在本地主机上的 Meilisearch 实例:

截图

如果我们在浏览器中导航到指定的 URL,就会看到 Meilisearch 界面。

截图

接下来,我们用不同的终端cd进入book-app-backend目录并使用以下命令安装Strapi-meilisearch插件:

$ npm 安装strapi-plugin-meilisearch

之后,我们重新运行npm run develop以使用新的meilisearch插件重建我们的 Strapi 应用程序。当我们在浏览器中打开 localhost URL 并登录时,我们将被定向到 Strapi 仪表板:

截图

接下来,让我们点击侧边栏上的meilisearch选项,并在 Settings 选项卡中输入 meilisearch 实例的 URL。

截图

点击保存。现在,通过单击复选框将图书收藏添加到 Collections 部分中的 meilisearch:

截图

这样,当我们刷新 meilisearch 实例时,我们将看到 Strapi 集合中的条目。

从Meilisearch获取图书数据

要在前端获取我们的图书数据,我们可以使用为我们提供的搜索路由(例如,这将获取 30 个图书数据:http://127.0.0.1:7700/indexes/book/search? limitu003d30)) 或者我们可以使用 meilisearch 包。在本教程中,我们将使用该软件包,因此我们需要先安装它。

  1. 在终端中,cd 进入 strapi-book-app 并输入以下命令:

$ npm 安装 meilisearch

1.接下来,在src/pages中的Home.js文件中添加如下导入:

从“meilisearch”导入MeiliSearch;

  1. 接下来,通过将 Allbooks 替换为空数组来修改图书状态。它应该如下所示:

const [books, setBooks] u003d useState([])

  1. 现在,在books状态后添加以下代码行:

// src/pages/Home.js

const fetchData u003d async () u003d> {

const client u003d new MeiliSearch({

主机:'http://127.0.0.1:7700',

})

const index u003d await client.getIndex('book')

const booksData u003d await index.search('*')

setBooks(booksData.hits)

}

上述函数在调用时会从通过meilisearch实例接收的 Strapi 图书集合中返回我们的数据。请注意,在search方法中,我们将 ***** 作为查询传递。这将获取我们所有的数据,限制为二十 (20),这是默认值。这可以是自定义。

要搜索特定数据,我们只需将其传递给search方法。我们将使用它来实现我们的搜索功能。

我们希望在我们的应用程序渲染时调用上述函数,因此我们将在useEffect挂钩中调用它。在Home组件中,使用sendData()函数修改useEffect挂钩,现在如下所示:

// src/pages/Home.js

使用效果(()u003d> {

拿来()

发送数据()

}, [])

有了这个,我们的 Strapi 图书收藏中的数据现在应该显示在我们的应用程序中。接下来,让我们确保当点击图书卡片时,我们会获取该特定图书的详细信息。

去做这个,

  1. 前往 src/pages/BookDetail.js 并首先添加以下导入:

从'meilisearch'导入MeiliSearch

1.接下来,修改useEffect钩子,如下所示:

// src/pages/BookDetail.js

使用效果(()u003d> {

const fetchData u003d async () u003d> {

const client u003d new MeiliSearch({

主机:'http://127.0.0.1:7700',

})

const index u003d await client.getIndex('book')

常量 bookData u003d 等待 index.getDocument(params.id)

setBook(bookData)

}

拿来()

}, [])

有了这个,当我们点击一本书时,我们应该看到这本书的详细信息。

实现搜索功能

对于搜索功能,当我们在搜索栏中输入查询时,它会将我们带到将查询附加到 URL 的搜索页面。我们将获取该查询并将其传递给 meilisearch 的 search 方法,然后该方法将返回相应的结果:

去做这个,

  1. 转到 src/pages/Search.js 并首先添加以下导入:

// src/pages/Search.js

从'meilisearch'导入MeiliSearch

从“反应”导入 {useEffect, useState}

1、接下来,在Search组件中的params变量后面添加如下代码行:

// src/pages/Search.js

const [books, setBooks] u003d useState([])

使用效果(()u003d> {

const fetchData u003d async () u003d> {

const client u003d new MeiliSearch({

主机:'http://127.0.0.1:7700',

})

const index u003d await client.getIndex('book')

const booksData u003d await index.search(params.query)

setBooks(booksData.hits)

}

拿来()

},[参数.查询])

上述代码将根据搜索查询返回所有匹配结果,并将其设置为books状态。现在让我们渲染获取的结果。 3. 将return语句中的div修改成现在这样:

// src/pages/Search.js

<div classNameu003d'searchPage 包装器'>

<div classNameu003d'books'>

{书?地图((书)u003d>(

<书

键u003d{book.id}

标题u003d{书名}

图像u003d{书.图像}

作者u003d{book.authors}

出版商u003d{book.publisher}

发布日期u003d{book.publishedDate}

idu003d{book.id}

/>

))}

</div>

</div>

这样,当我们在搜索栏中搜索书籍时,我们将在搜索页面中看到结果。

使用 Intersection Observer API 实现无限滚动

对于无限滚动功能,我们将从 meilisearch 返回的书限制为 15 个,然后当我们滚动到页面底部时,我们将获取并附加另外 15 个数据。

为此,我们将使用Intersection Observer API来了解我们何时到达页面底部,然后从 meilisearch 以 15 个为单位返回书籍,我们将使用 limit 和 ** offset**参数,可以在作为search方法的第二个参数传递的对象中指定。

使用 Intersection Observer 获取新数据

Intersection ObserverAPI 监控观察到的元素何时可见或何时到达预定义的位置,然后触发提供给它的回调函数。要使用此 API,我们将首先在我们获取的数据的底部创建一个元素,该元素将是观察到的元素。然后,当这个元素可见时,我们将调用回调函数,该函数将负责获取和挂起新书数据。

  1. 在 Home.js 文件中添加以下导入:

从“反应”导入 {useRef,useCallback}

1、在此之后,在div的结束标记(</div>)之后添加以下代码行,其className为books

// src/pages/Home.js

<div classNameu003d'loader' refu003d{observerElem}>

{books.length !u003du003d 0 &&

<span>{hasNextPage ? 'Loading...' : '没有书了'}</span>

}

</div>

在上面,我们创建了_div_元素,我们要使用Intersection Observers 观察。我们添加了_ref_属性,所以我们可以直接访问它。以上_div_将显示 Loading... or **n***o** 剩余书籍 ***取决于_hasNextPage_这将是一个布尔状态这将是真或假,具体取决于是否还有要获取的数据。

1.接下来,在URL变量后添加如下代码:

// src/pages/Home.js

constobserverElem u003d useRef(null)

常量 [hasNextPage, setHasNextPage] u003d useState(true)

1、接下来在hasNextPage状态后添加如下代码行:

// src/pages/Home.js

const handleObserver u003d useCallback((entries) u003d> {

常量 [目标] u003d 条目

if(target.isIntersecting && hasNextPage) {

console.log('相交')

}

}, [hasNextPage])

使用效果(()u003d> {

常量元素u003dobserverElem.current

常量选项 u003d { 阈值:0 }

const观察者u003d新的IntersectionObserver(handleObserver,选项);

观察者。观察(元素)

return () u003d> 观察者.unobserve(元素)

}, [hasNextPage, handleObserver])

上面的代码会检测观察到的元素何时进入视口,然后调用_handleObserver_callback函数。现在,当我们在浏览器中滚动到页面底部并检查控制台时intersected将被记录。

接下来,让我们创建一个函数,该函数将在我们滚动到页面底部时获取和附加书籍数据。为此,我们将修改fetchData函数以在任何时候使用 limitoffset 参数调用时获取 15 本书的新数据,然后我们会将新获取的书籍附加到books状态。

去做这个,

1、首先在hasNextPage状态后添加如下代码:

// src/pages/Home.js

const [offset, setOffset] u003d useState(0)

常量 [lastPage, setLastPage] u003d useState({})

  1. 接下来,将 fetchData 函数修改为如下所示:

// src/pages/Home.js

const fetchData u003d async () u003d> {

const client u003d new MeiliSearch({

主机:'http://127.0.0.1:7700',

})

const index u003d await client.getIndex('book')

const booksData u003d await index.search('*', {

限制:15,

偏移量:偏移量

})

setBooks([...books, ...booksData.hits])

setLastPage(booksData)

}

接下来,我们需要调用handleObserver中的fetchData(),这样当我们滚动到页面底部时,它就会被调用。

  1. 修改handleObserver函数现在如下所示:

// src/pages/Home.js

const handleObserver u003d useCallback((entries) u003d> {

常量 [目标] u003d 条目

if(target.isIntersecting && hasNextPage) {

拿来()

}

}, [fetchData, hasNextPage])

1、最后在fetchData函数后添加如下代码:

// src/pages/Home.js

使用效果(()u003d> {

setOffset(books.length)

如果(books.length < lastPage.nbHits){

setHasNextPage(true)

}别的{

setHasNextPage(假)

}

},[书籍])

这样,我们就完成了无限滚动功能的实现。当我们滚动到页面底部时,将显示新书。

结论

在本教程中,我们通过构建图书应用程序学习了如何使用 meilisearch 在 Strapi 中实现无限滚动和搜索功能。

参考文献

1.查看Meilisearch文档。

2.点击这里查看本教程的完整源代码。

Logo

更多推荐