You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS实现作品分类与年份双条件筛选及无结果提示

实现分类与年份的组合筛选及无结果提示

问题背景

基于NextJS开发的作品集项目,已实现分类筛选功能,需要新增年份筛选并支持组合筛选(同时满足分类和年份条件),且在无筛选结果时显示提示信息。


解决方案

一、实现组合筛选

1. 新增年份筛选状态

在WorkPage组件中添加年份状态管理:

const [selectedCat, setSelectedCat] = useState("");
const [selectedYear, setSelectedYear] = useState(""); // 新增年份筛选状态

2. 创建年份筛选组件(FilterYear.js)

// FilterYear.js
import works from "@/content/works/data.json"

export default function FilterYear({selectedYear, onSelect}) {
    // 提取所有唯一年份并按倒序排列
    const years = Array.from(new Set(works.map(w => w.year))).sort((a, b) => b - a);

    return (
        <div>
            <ul>
                <li
                    className={!selectedYear ? "bg-indigo-50 p-2 rounded-md" : "p-2"}
                    onClick={() => onSelect("")}
                >
                    Все года
                </li>
                {years.map((year, i) => {
                    const isSelected = year.toString() === selectedYear
                    return (
                        <li key={i}
                            className={isSelected ? "bg-indigo-50 p-2 rounded-md" : "p-2"}
                            onClick={() => onSelect(year.toString())}
                        >
                            {year}
                        </li>
                    )
                })}
            </ul>
        </div>
    )
}

3. 修改筛选逻辑

替换原有的filteredCat逻辑,同时判断分类和年份条件:

const filteredWorks = work.filter(item => {
    // 分类匹配规则:无选中分类则全部匹配,否则匹配包含该分类的项
    const matchesCat = !selectedCat || item.category.includes(selectedCat);
    // 年份匹配规则:无选中年份则全部匹配,否则匹配年份完全一致的项
    const matchesYear = !selectedYear || item.year.toString() === selectedYear;
    // 必须同时满足两个条件
    return matchesCat && matchesYear;
});

4. 在页面中引入年份筛选组件

在WorkPage的导入和渲染部分添加:

// 导入组件
import FilterYear from "@/components/filter-year";

// 页面渲染时,在FilterWork下方添加
<div className="flex gap-4 mb-6">
    <FilterWork
        selectedCat={selectedCat}
        onSelect={setSelectedCat}
    />
    <FilterYear
        selectedYear={selectedYear}
        onSelect={setSelectedYear}
    />
</div>

二、添加无结果提示

在作品列表渲染区域,判断筛选结果长度,为空时显示提示:

<div className={styles.featuredWorkInner}>
    {filteredWorks.length === 0 ? (
        <p className="text-gray-500 py-8 text-center">未找到内容,请选择其他筛选条件</p>
    ) : (
        filteredWorks.map((workItem) => (
            <Work key={workItem.title} item={workItem} />
        ))
    )}
</div>

完整修改后的WorkPage代码

import { useState } from "react"
import Seo from "@/components/global/seo";
import Work from "../components/work";
import {getAllWork} from "@/lib/getAllData";
import styles from "@/styles/home/featuredWork.module.css"

import FilterWork from "@/components/filter-work";
import FilterYear from "@/components/filter-year";

export async function getStaticProps() {
    const work = getAllWork();

    return {
        props: {
            work,
        },
    };
}

export default function WorkPage({work}) {
     const [selectedCat, setSelectedCat] = useState("");
     const [selectedYear, setSelectedYear] = useState("");

    const filteredWorks = work.filter(item => {
        const matchesCat = !selectedCat || item.category.includes(selectedCat);
        const matchesYear = !selectedYear || item.year.toString() === selectedYear;
        return matchesCat && matchesYear;
    });

    return (
        <div>
            <Seo
                title="Все работы Колтан Леонида"
                description="Здесь собраны некоторые из работ разработчика Колтан Леонида"
                ogImageUrl={`http://localhost:3000/api/og?title=Все работы Колтан Леонида&description=Здесь собраны некоторые из работ разработчика Колтан Леонида`}
            />
            <section className='px-6'>
                <div className='wrapper'>
                    <h1 className='sectionTitle'>Проекты</h1>
                    <div className="flex gap-4 mb-6">
                        <FilterWork
                            selectedCat={selectedCat}
                            onSelect={setSelectedCat}
                        />
                        <FilterYear
                            selectedYear={selectedYear}
                            onSelect={setSelectedYear}
                        />
                    </div>
                    <div className={styles.featuredWorkInner}>
                        {filteredWorks.length === 0 ? (
                            <p className="text-gray-500 py-8 text-center">未找到内容,请选择其他筛选条件</p>
                        ) : (
                            filteredWorks.map((workItem) => (
                                <Work key={workItem.title} item={workItem} />
                            ))
                        )}
                    </div>
                </div>
            </section>
        </div>
    )
}

内容的提问来源于stack exchange,提问作者Лео

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 22:44:56