type
Post
status
Published
date
Feb 8, 2026
slug
nextjs-shopping-platform-013
summary
tags
Next.js
category
编程学习
icon
password
😀

1. Section Intro

In this section, we'll be doing quite a few things. First, we're going to use a ShadCN drawer component fot the categories. We will have a button with an icon to the left of the logo in the header on main pages. This will open a drawer with the categories.
在本章节中,我们将要完成多项任务。首先,我们将使用 ShadCN 的抽屉组件来展示商品分类。我们会在主页的页眉中,于 Logo 左侧添加一个带有图标的按钮。点击该按钮将打开一个包含商品分类的抽屉。
Then we're going to create the featured product banner. So if the product is marked as featured and has a banner, it will show up im this component. There will be arrow buttons to scroll through the banners on the homepage.
接下来,我们将创建精选商品横幅组件。如果某个商品被标记为精选商品并且配有横幅图片,它将显示在此组件中。我们会添加左右箭头按钮,让用户可以在首页滚动浏览不同的横幅。
Next, we want to work on the search and filtering. We're going to create the search form in a component and put it in the header. Right now, the input is just hardcoded.
然后,我们将着手实现搜索和筛选功能。我们会创建一个搜索表单组件,并将其放置在页眉中。目前,搜索输入框只是硬编码的占位符。
We'll create a search page for that form to submit to and we will get the search params like category, query and sort.
我们将创建一个搜索页面作为表单的提交目标,并从 URL 参数中获取搜索条件,如分类、搜索关键词和排序方式。
Then we need to take those values and use them in the action to apply the filters.
接着,我们需要获取这些参数值,并在数据请求动作中使用它们来应用相应的筛选条件。
We also need to add all the filter links on to the search page. So they can click on a specific category, rating, price, etc.
我们还需要在搜索页面上添加所有的筛选链接,这样用户就可以点击特定的分类、评分、价格等条件进行筛选。
We'll also implement sorting by price, rating and date.
最后,我们还将实现按价格、评分和日期进行排序的功能。

2. Category Drawer 分类抽屉组件

We are going to start on the drawer component on the homepage. This will show a list of categories so that we can navigate to the category pages.
我们将从首页的抽屉组件开始。这个组件将显示分类列表,以便我们可以导航到各个分类页面。

Get All Categories Action 获取所有分类的动作

Before we create the component, let's add the action that will give us the data.
在创建组件之前,我们先添加一个用于获取数据的动作(Action)。
Open the lib/actions/product.actions.ts file and add the following function:
打开 lib/actions/product.actions.ts 文件,添加以下函数:
This is simple. We are just getting the categories and the count of products in each category.
这个操作很简单。我们只是获取所有分类以及每个分类中的商品数量。

ShadCN Drawer Component ShadCN 抽屉组件

We need to install the ShadCN Drawer component. Open a terminal and run the following command:
我们需要安装 ShadCN 的抽屉组件。打开终端并运行以下命令:

Categories Drawer Component 分类抽屉组件

Let's create a new component at components/shared/header/categories-drawer.tsx and add the following code:
让我们在 components/shared/header/categories-drawer.tsx 创建一个新组件,并添加以下代码:
We are bringing in the getAllCategories action from the product.actions.ts file. We are also using the Drawer component from the ShadCN library. We map over the categories and render a button for each category. The DrawerClose component is used to close the drawer when the button is clicked and we can have it navigate to the category page, which we will create later.
我们从 product.actions.ts 文件中引入了 getAllCategories 动作。同时,我们使用了 ShadCN 库中的 Drawer 组件。我们遍历所有分类并为每个分类渲染一个按钮。DrawerClose 组件用于在点击按钮时关闭抽屉,并且可以让它导航到分类页面(我们将在稍后创建该页面)。

Add Categories Drawer to Header 将分类抽屉添加到页眉

Open the components/shared/header/index.tsx file and add import the CategoriesDrawer component:
打开 components/shared/header/index.tsx 文件,导入 CategoriesDrawer 组件:
It's up to you on where you want to place this. Since we're going to have it open on the left, I am going to place it to the left of the logo. If you want to add it to the menu on the right, you can do that as well.
你可以自行决定放置的位置。由于我们打算让它从左侧打开,我将把它放在 Logo 的左侧。如果你想把它添加到右侧的菜单中,也可以这样做。
Here is where I will embed it:
以下是我将嵌入它的位置:
I also added a class of ml-4 to the logo so that it is not right next to the drawer.
我还为 Logo 添加了 ml-4 类,这样它就不会紧挨着抽屉按钮了。
Now you should be able to click on the button and see the drawer open.
现在你应该能够点击按钮并看到抽屉打开了。

3. Featured Products Carousel 精选商品轮播组件

We are going to add a carousel on the homepage that will show the featured products and their banners.
我们将在首页添加一个轮播组件,用于展示精选商品及其横幅图片。

Carousel Component & Autoplay Plugin 轮播组件与自动播放插件

We are going to use the ShadCN Carousel component and the Embla Carousel Autoplay plugin so that it plays automatically when you visit the page.
我们将使用 ShadCN 的轮播组件和 Embla Carousel 的自动播放插件,这样当你访问页面时,轮播就会自动播放。

Featured Products Action 精选商品动作

We need to create an action that will get the featured products. Open the lib/actions/product.actions.ts file and add the following function:
我们需要创建一个动作来获取精选商品。打开 lib/actions/product.actions.ts 文件,添加以下函数:

Carousel Component 轮播组件

Create a new file at components/shared/product/product-carousel.tsx and add the following code:
components/shared/product/product-carousel.tsx 创建一个新文件,并添加以下代码:
Let's go over this code.
让我们来查看一下这段代码。
We are bringing in the Carousel component from the ShadCN library. We are also bringing in the Autoplay plugin from the embla-carousel-autoplay library. We are also bringing in the Product type from the types.ts file.
我们从 ShadCN 库中引入了 Carousel 组件,从 embla-carousel-autoplay 库中引入了 Autoplay 插件,还从 types.ts 文件中引入了 Product 类型。
The component takes in a data prop. We set the Carousel component with an option of loop: true and plugins of Autoplay. We are also mapping over the data and rendering a CarouselItem for each product. We are also rendering a CarouselPrevious and CarouselNext component.
该组件接收一个 data 属性。我们为 Carousel 组件设置了 loop: true 选项和 Autoplay 插件。我们还遍历数据,为每个商品渲染一个 CarouselItem。同时还渲染了 CarouselPreviousCarouselNext 组件。
Let's bring in both the action and the component into the app/(root)/page.tsx file.
让我们把动作和组件都引入到 app/(root)/page.tsx 文件中。
Then get the featured products. Add this above the return statement:
然后获取精选商品。在 return 语句上方添加以下代码:
Now in the return, check if there are any featured products. If there are, render the ProductCarousel component.
现在在 return 中,检查是否有精选商品。如果有,就渲染 ProductCarousel 组件。
Now you should see the carousel on the homepage.
现在你应该能在首页看到轮播组件了。
notion image

4. Search Component 搜索组件

We are going to create a search component that allows users to search for products with a keyword text field and a category dropdown. Once we get to the search page, there will be all kinds of filters that the user can use to filter the products such as the price, rating, and sort.
我们将创建一个搜索组件,允许用户使用关键词文本字段和分类下拉菜单搜索产品。进入搜索页面后,用户可以使用各种筛选器来筛选产品,例如价格、评分和排序。
Let's create a new file at components/shared/header/search.tsx and add the following code:
让我们在 components/shared/header/search.tsx 创建一个新文件,并添加以下代码:
We are using the getAllCategories action to get all the categories from the database. We are using the Select component from the @/components/ui/select component. We are using the SelectTrigger component to trigger the dropdown and the SelectContent component to display the dropdown options. We are using the Input component from the @/components/ui/input component. We also have some icons from the lucide-react package.
我们使用 getAllCategories 动作从数据库获取所有分类。我们使用 @/components/ui/select 组件中的 Select 组件。我们使用 SelectTrigger 组件来触发下拉菜单,使用 SelectContent 组件来显示下拉选项。我们使用 @/components/ui/input 组件中的 Input 组件。我们还使用了 lucide-react 包中的一些图标。
The form action is set to /search. We will create the search page soon.
表单动作设置为 /search。我们稍后会创建搜索页面。

Use The Search Component 使用搜索组件

Now open the components/shared/header/index.tsx file and import the Search component:
现在打开 components/shared/header/index.tsx 文件并导入 Search 组件:
We are going to show the search component within the header on large screens but on small screens, we'll show it in the menu drawer.
我们将在大屏幕上在页眉中显示搜索组件,但在小屏幕上,我们会将其显示在菜单抽屉中。
Add the following code to the Header component right above the Menu component:
将以下代码添加到 Header 组件中,放在 Menu 组件的正上方:
Now open the components/shared/header/menu.tsx file and import the Search component:
现在打开 components/shared/header/menu.tsx 文件并导入 Search 组件:
And add the <div> with the <Search /> component within the <SheetContent> component:
并在 <SheetContent> 组件中添加包含 <Search /> 组件的 <div>

Add Search Page 添加搜索页面

The search page ultimately will have a lot of filters and so on, but for now, I just want the page to show, so let's just show some text that says "Search Page".
搜索页面最终会有很多筛选器等功能,但现在,我只想让页面显示出来,所以让我们只显示一些写着"搜索页面"的文本。
Create a file at app/(root)/search/page.tsx and add the following code:
app/(root)/search/page.tsx 创建一个文件,并添加以下代码:
Now if you submit the search form, you should see the search page.
现在如果你提交搜索表单,你应该能看到搜索页面。
Next, we will add some new functionality to the getAllProducts action so that we can filter the products by category, price, rating, etc.
接下来,我们将为 getAllProducts 动作添加一些新功能,以便我们可以按分类、价格、评分等筛选产品。

5. Search Page 搜索页面

Now that we have the search component that takes us to the search page, there is quite a bit to do. We need to add the filters to the getAllProducts action for things like category, price, sorting, etc. We need to add the filter UI and handlers to the search page. There will be a lot of logic to do here, so we will go through it step by step.
现在我们有了带我们到搜索页面的搜索组件,还有很多工作要做。我们需要为 getAllProducts 动作添加筛选器,用于分类、价格、排序等功能。我们需要在搜索页面添加筛选器UI和处理器。这里会有很多逻辑需要处理,所以我们会一步一步来完成。
I struggled with how I wanted to do this. I didn't want to just add a bunch of code to the action without being able to test it. I thought about writing some Jest tests, but that got really complicated and I didn't want to spend too much time with Jest.
我在纠结该如何实现这个功能。我不想在无法测试的情况下就往动作里添加一堆代码。我考虑过写一些Jest测试,但那变得太复杂了,而且我不想在Jest上花费太多时间。
So I think the best thing is to start working on the search page and add to the action as we go so that we can test the filters.
所以我认为最好的办法是开始处理搜索页面,并在过程中逐步添加到动作中,这样我们就可以测试筛选器了。
Let's open the app/(root)/search/page.tsx file.
让我们打开 app/(root)/search/page.tsx 文件。
Let's bring in the imports we need:
让我们引入所需的导入:
We are using the getAllCategories and getAllProducts actions from the product.actions file.
我们使用来自 product.actions 文件的 getAllCategoriesgetAllProducts 动作。
Let's create a basic component that takes in searchParams:
让我们创建一个接收 searchParams 的基础组件:
We destructured the searchParams to get the search query, category, price, rating, sort, and page and we are logging them to the console. We are also setting default values for them.
我们解构了 searchParams 来获取搜索查询、分类、价格、评分、排序和页码,并将它们输出到控制台。我们还为它们设置了默认值。
Go into the search component and select a category and type something in the search bar. You should see the search query, category, price, rating, sort, and page in the console.
进入搜索组件,选择一个分类并在搜索栏中输入一些内容。你应该能在控制台中看到搜索查询、分类、价格、评分、排序和页码。
Delete the console log statement.
删除控制台日志语句。
Now let's have it call the getAllProducts action and pass in the search query, category, price, rating, sort, and page and log the products.
现在让我们调用 getAllProducts 动作,传入搜索查询、分类、价格、评分、排序和页码,并输出产品信息。
Add the following above the return statement:
在return语句上方添加以下内容:

Edit The Action 编辑动作

Now let's open the lib/actions/product.actions.ts file and go to the getAllProducts action. Right now it just takes in the query, limit, and page. We need to add the category, price, rating, and sort.
现在让我们打开 lib/actions/product.actions.ts 文件,找到 getAllProducts 动作。目前它只接收查询、限制和页码参数。我们需要添加分类、价格、评分和排序参数。
Add the following parameters to the getAllProducts action:
将以下参数添加到 getAllProducts 动作中:

Showing The Results 显示结果

Let's add the following to the search page return statement:
让我们将以下内容添加到搜索页面的return语句中:
You should see all products. We have not implemented the filters yet, so we are just showing all products.
你应该能看到所有产品。我们还没有实现筛选器,所以现在只是显示所有产品。

View All Products Button 查看所有产品按钮

This is essentially the products page. It uses pagination and will have all kinds of filters. So on the homepage, I want a button to go to this /search page under the new arrivals section.
这本质上是产品页面。它使用分页功能,并将有各种筛选器。所以在首页上,我想在新到货部分下方添加一个按钮,用于跳转到这个 /search 页面。
Create a new file at components/view-all-products-button.tsx and add the following code:
components/view-all-products-button.tsx 创建一个新文件,并添加以下代码:
Now let's import it into the app/page.tsx file and import it:
现在让我们将它导入到 app/page.tsx 文件中:
Add it below the ProductList component:
将它添加到 ProductList 组件下方:
In the next few lessons, we will start to add filters and sorting.
在接下来的几节课中,我们将开始添加筛选器和排序功能。

6. Search Filters 搜索过滤器

When we visit the search page, we are able to add query params to the URL and those are getting passed to the getAllProducts action. However, we aren't using them. So let's add them to the getAllProducts action. 当我们访问搜索页面时,可以向 URL 添加查询参数,这些参数会被传递到 getAllProducts 操作。然而,我们并没有使用它们。所以让我们将它们添加到 getAllProducts 操作中。
So we want to handle the values in the action and then use them to filter the products. 所以我们想要在操作中处理这些值,然后使用它们来过滤产品。

Query Filter 查询过滤器

Let's start with the query filter. When we type in the search bar, the query is added to the url and added to the getAllProducts call in the search page. 让我们从查询过滤器开始。当我们在搜索栏中输入时,查询会被添加到 URL 中,并添加到搜索页面的 getAllProducts 调用中。
Open the action file at lib/actions/products.actions.ts and add the following code to the getAllProducts function right at the top: 打开位于 lib/actions/products.actions.ts 的操作文件,并将以下代码添加到getAllProducts 函数的最顶部:
You have to import the Prisma client as well: 你还需要导入 Prisma 客户端:
The ProductWhereInput in the context of Prisma refers to a filter input type generated by Prisma for the Product model. It allows you to define conditions (or filters) for querying records from the Product table in your database. 在 Prisma 上下文中的 ProductWhereInput 是指 Prisma 为 Product 模型生成的过滤器输入类型。它允许你定义条件(或过滤器),用于从数据库的 Product 表查询记录。
We are checking if the query is not all (the default) and if it is not, we are adding a name filter to the query. We are using the contains operator to check if the query is contained in the name of the product. We are also using the insensitive mode to make the search case-insensitive. We are using the as Prisma.StringFilter to tell TypeScript that we are using the StringFilter type from the Prisma client. For some reason, when I added the "mode" option, I got a type error. So I had to add the as Prisma.StringFilter to tell TypeScript that we are using the StringFilter type from the Prisma client. 我们正在检查查询是否不是 all(默认值),如果不是,我们会向查询添加一个 name 过滤器。我们使用 contains 运算符来检查查询是否包含在产品名称中。我们还使用 insensitive 模式使搜索不区分大小写。我们使用 as Prisma.StringFilter 来告诉 TypeScript 我们正在使用 Prisma 客户端的 StringFilter 类型。出于某种原因,当我添加 "mode" 选项时,出现了类型错误。所以我不得不添加 as Prisma.StringFilter 来告诉 TypeScript 我们正在使用 Prisma 客户端的 StringFilter 类型。
Now we need to add it to the actual findMany function: 现在我们需要将它添加到实际的 findMany 函数中:
Now try your search component. It should filter the products based on the query. If you are using the sample data, try searching for shirt or polo. 现在尝试你的搜索组件。它应该根据查询过滤产品。如果你使用的是示例数据,尝试搜索 shirtpolo

Category Filter 类别过滤器

Now let's add the category filter. We will use the same approach as the query filter. We will add a category filter to the query and add it to the findMany function. 现在让我们添加类别过滤器。我们将使用与查询过滤器相同的方法。我们将向查询添加一个 category 过滤器,并将其添加到 findMany 函数中。
Start with the action file. Add the following code to the getAllProducts function: 从操作文件开始。将以下代码添加到 getAllProducts 函数中:
Now add it to the where in the findMany function: 现在将其添加到 findMany 函数中的 where 中:
Now either open the category drawer and click on a category or enter a URL like this - http://localhost:3000/search?category=Men's Dress Shirts 现在打开类别抽屉并点击一个类别,或者输入这样的 URL - http://localhost:3000/search?category=Men's Dress Shirts

Price Filter 价格过滤器

Let's add the price filter 让我们添加价格过滤器
Now add it to the where in the findMany function: 现在将其添加到 findMany 函数中的 where 中:
You can test this by entering a URL like this - http://localhost:3000/search?price=10-40 你可以通过输入这样的 URL 来测试这一点 - http://localhost:3000/search?price=10-40
This will show you the products with a price between 10 and 40. 这将向你显示价格在 10 到 40 之间的产品。

Rating Filter 评分过滤器

Now let's add the rating filter. We will use the same approach as the previous filters. 现在让我们添加评分过滤器。我们将使用与之前过滤器相同的方法。
Now add it to the where in the findMany function: 现在将其添加到 findMany 函数中的 where 中:
Right now all ratings are 0, but you can still test with these URLs: 目前所有评分都是 0,但你可以使用这些 URL 测试:

7. Get Filter URL Function 获取过滤器URL函数

We are going to have a UI that allows us to filter our search results. Remember, we do this with query strings in the URL. So we need to create a function to construct this URL. 我们将拥有一个允许我们过滤搜索结果的UI。记住,我们通过URL中的查询字符串来实现这一点。所以我们需要创建一个函数来构建这个URL。
An example of what a URL may look like is: URL可能的样子示例如下:
Add the following function above the return statement in the app/(root)/search/page.tsx file: 在 app/(root)/search/page.tsx 文件的 return 语句上方添加以下函数:
The function takes in optional params of the following: 该函数接受以下可选参数:
  • c (category) 类别
  • s (sort order) 排序顺序
  • p (price) 价格
  • r (rating) 评分
  • pg (page number) 页码
The params object (q, category, price, rating, sort, and page) corresponds to a filter or sort option. These values come from the searchParams object, which stores the current state of each filter. params 对象(q、category、price、rating、sort 和 page)对应于过滤器或排序选项。这些值来自 searchParams 对象,该对象存储每个过滤器的当前状态。
Then we check if the optional params are truthy. If they are, we add them to the params object. 然后我们检查可选参数是否为真。如果是,我们将它们添加到 params 对象中。
Finally, we return the URL with the query string using new URLSearchParams(params).toString(), which converts the params object into a query string. 最后,我们使用 new URLSearchParams(params).toString() 返回带有查询字符串的 URL,该方法将 params 对象转换为查询字符串。
Let's test it out. Add this anywhere in the search page return statement: 让我们测试一下。在搜索页面的 return 语句中任意位置添加以下内容:
You will see the URL on the page with the values. They should all be the default except for the category, which we passed in. Also, the query comes from the URL, which comes from the search component. 你会在页面上看到带有值的 URL。除了我们传入的类别外,它们都应该是默认值。此外,查询来自 URL,而 URL 来自搜索组件。
Delete that line. I just wanted to show you how the function works. In the next lesson, we will start to build the UI. 删除那一行。我只是想向你展示该函数的工作原理。在下一课中,我们将开始构建UI。
8. Category & Price UI Filters

8. Search Filter UI 搜索过滤器UI

We have our action handling the filters, now we need to actually be able to use them in our UI. 我们已经有了处理过滤器的操作,现在我们需要能够在我们的UI中实际使用它们。
Open the app/(root)/search/page.tsx file. 打开 app/(root)/search/page.tsx 文件。

Category Links 类别链接

We need have our function that will add the params we need including the category to our URL. I want to list out the categories and be able to click on it and add the category to our URL. This means we need to fetch the categories. So let's import the getCategories action: 我们需要有一个函数,它会将我们需要的参数(包括类别)添加到我们的URL中。我想列出所有类别,并且能够点击它并将类别添加到我们的URL中。这意味着我们需要获取类别。所以让我们导入 getCategories 操作:
Now let's get the categories. Add this line right above where we get our products: 现在让我们获取类别。在获取产品的代码正上方添加这一行:
Now in the return, let's have a link for "any" category and then map over the categories and create a link for each one. 现在在 return 中,让我们为 "任意" 类别创建一个链接,然后遍历类别并为每个类别创建一个链接。
The return should look like this: return 应该看起来像这样:
We are setting the href to the getFilterUrl function that we created earlier, which adds the category to our URL. Then we call our action with the category. 我们将 href 设置为我们之前创建的 getFilterUrl 函数,该函数将类别添加到我们的URL中。然后我们使用类别调用我们的操作。

Price Links 价格链接

For prices, we will specify a range and then have links for each price range. So let's create an array of price ranges. 对于价格,我们将指定一个范围,然后为每个价格范围创建链接。所以让我们创建一个价格范围数组。
Put this above the main function right below the imports: 将这段代码放在主函数上方,紧挨着导入语句下方:
If you want to use different or more price ranges, you can add them here. 如果你想使用不同的或更多的价格范围,你可以在这里添加它们。
Now add the links right under the closing </div> of the category links. Make sure you are still within the filter-links div or the layout will not look right. 现在在类别链接的结束 </div> 正下方添加链接。确保你仍然在 filter-links div 内,否则布局看起来会不对。
We are mapping over the prices and creating a link for each one. We are also setting the href to the getFilterUrl function that we created earlier, which adds the price to our URL. Then we call our action with the price. 我们正在遍历价格并为每个价格创建一个链接。我们还将 href 设置为我们之前创建的 getFilterUrl 函数,该函数将价格添加到我们的URL中。然后我们使用价格调用我们的操作。

9. Rating & Query Filter Links 评分和查询过滤器链接

Now we will add links to filter the ratings and query text. 现在我们将添加链接来过滤评分和查询文本。

Rating Links 评分链接

Let's create an array of ratings right under the prices array. 让我们在价格数组的正下方创建一个评分数组。
Now add the following right under the closing </div> of the price links. Make sure you are still within the filter-links div or the layout will not look right. 现在在价格链接的结束 </div> 正下方添加以下内容。确保你仍然在 filter-links div 内,否则布局看起来会不对。
We are doing the same thing, mapping through the ratings and creating a link for each one. 我们正在做同样的事情,遍历评分并为每个评分创建一个链接。

Query Text 查询文本

Right now we are stuck with whatever query we have in the URL. So let's show the query text along with the category, price, rating and a button to clear the filters. 现在我们被URL中的查询所限制。所以让我们显示查询文本以及类别、价格、评分和一个清除过滤器的按钮。
Find the div that wraps the right column: 找到包裹右侧列的div:
And add this inside of it: 并在其中添加以下内容:
First, we are checking if the query is not all and not empty. If it is not, we are showing the query text. Then we are checking if the category is not all and not empty. If it is not, we are showing the category text. Then we are checking if the price is not all. If it is not, we are showing the price text. Then we are checking if the rating is not all. If it is not, we are showing the rating text. Then we are checking if the query is not all and not empty or the category is not all and not empty or the rating is not all or the price is not all. If it is not, we are showing a button to clear the filters. 首先,我们检查查询是否不是 all 且不为空。如果不是,我们将显示查询文本。然后我们检查类别是否不是 all 且不为空。如果不是,我们将显示类别文本。然后我们检查价格是否不是 all。如果不是,我们将显示价格文本。然后我们检查评分是否不是 all。如果不是,我们将显示评论文本。然后我们检查查询是否不是 all 且不为空,或者类别是否不是 all 且不为空,或者评分是否不是 all,或者价格是否不是 all。如果是,我们将显示一个清除过滤器的按钮。
In the next lesson, we will add the sorting. 在下一课中,我们将添加排序。

10. Sorting Products 添加排序功能

Now we are going to add the ability to sort the results. We have to edit both the action and the page component UI. 现在我们将添加对结果进行排序的功能。我们需要同时编辑 action 和页面组件 UI。

Edit the action 编辑 action

Let's start by editing the action. Open the lib./actions/product.actions.ts file and go to the getAllProducts method. 让我们从编辑 action 开始。打开 lib./actions/product.actions.ts 文件,找到 getAllProducts 方法。
It already takes in a sort parameter. Change the following query: 它已经接收了一个 sort 参数。更改以下查询:
To this: 改成这样:
We are adding a new orderBy parameter. We can sort by price or rating or createdAt. 我们添加了一个新的 orderBy 参数。我们可以按 price(价格)、rating(评分)或 createdAt(创建时间)排序。

Edit The Search Page 编辑搜索页面

Now open the app/(root)/search/page.tsx file and add the following array at the top of the file with the other arrays: 现在打开 app/(root)/search/page.tsx 文件,在文件顶部与其他数组一起添加以下数组:
Now go to the comment "SORTING HERE" and replace it with the following code: 现在找到注释 "SORTING HERE",并用以下代码替换它:
We are mapping over the sortOrders array and creating a link for each one. We are also adding a class to the link if the sort is the same as the current sort. 我们正在遍历 sortOrders 数组,并为每个排序选项创建一个链接。如果排序方式与当前排序相同,我们还会为链接添加一个类。
You should now w be able to sort the results by price, rating, and createdAt. 现在你应该能够按价格、评分和创建时间对结果进行排序了。

11. Dynamic Metadata 动态元数据

This is a nice touch to what we have so far. For the title, we can make it dynamic based on the filters. 这是对我们目前所做工作的一个很好的补充。对于标题,我们可以根据筛选条件使其动态变化。
Remember, we can just export a function called generateMetadata from the page component adn add things like a title, description, etc. 记住,我们可以从页面组件中导出一个名为 generateMetadata 的函数,并添加标题、描述等内容。
So if we add the following function above the main SearchPage function in the app/(root)/search/page.tsx file: 所以如果我们在 app/(root)/search/page.tsx 文件的主 SearchPage 函数上方添加以下函数:
It will add the title to the page. 它会将标题添加到页面上。
Let's make this very dynamic by taking in the search parameters and using them to create the title. 让我们通过接收搜索参数并使用它们来创建标题,使这个功能更加动态。
Add the following searchParams to the function: 向函数添加以下 searchParams:
Now we can add some conditional logic to the function and return the title based on the search parameters. 现在我们可以向函数添加一些条件逻辑,并根据搜索参数返回标题。
We are checking for the query, category, price, and rating parameters and if they are not all, we are adding them to the title. If there are no filters, we are just returning the default title of Search Products. 我们正在检查查询、类别、价格和评分参数,如果它们不是 all,我们就将它们添加到标题中。如果没有筛选条件,我们就返回默认标题 Search Products(搜索产品)。

📎 参考文章

  • 一些引用
  • 引用文章
 
💡
欢迎您在底部评论区留言,一起交流~
上一篇
第一节 大脑:重新认识你自己
下一篇
Harness Engineering - 搭建Mini Harness
Loading...