如何在Next.js+Strapi的商品详情页实现动态面包屑组件?
实现动态面包屑导航步骤
1. 修正Strapi数据获取逻辑
当前getStaticProps中通过slug查询category的逻辑有误,商品的slug和分类slug并不一致,应该从商品关联的分类数据中直接获取。调整API请求,让返回的商品数据包含完整的分类关联信息:
export async function getStaticProps({ params: { slug } }) { // 关键:通过populate=category获取商品关联的分类详情 const product = await fetchDataFromApi( `/api/products?populate[category][populate]=*&filters[slug][$eq]=${slug}` ); // 从商品数据中提取分类信息,无需单独查询分类表 const category = product.data[0]?.attributes?.category; const products = await fetchDataFromApi( `/api/products?populate=*&[filters][slug][$ne]=${slug}` ); return { props: { category, product, products, slug, }, }; }
2. 实现Breadcrumbs组件
创建或完善@/components/breadcrumbs.js组件,用于渲染面包屑导航链:
import Link from "next/link"; const Breadcrumbs = ({ items }) => { return ( <div className="text-sm text-gray-600 mb-4 flex items-center gap-2"> {items.map((item, index) => ( <div key={index} className="flex items-center"> {index > 0 && <span className="mx-2">/</span>} {item.isCurrent ? ( <span className="font-medium text-gray-800">{item.label}</span> ) : ( <Link href={item.href} className="hover:text-amber-500"> {item.label} </Link> )} </div> ))} </div> ); }; export default Breadcrumbs;
3. 在商品详情页挂载面包屑
在ProductDetails组件中构建面包屑数据,并将组件渲染到页面顶部:
const ProductDetails = ({ category, product, slug }) => { // ... 保留原有状态和方法 const p = product?.data?.[0]?.attributes; // 构建面包屑导航数据 const breadcrumbItems = [ { label: "首页", href: "/" }, { label: category?.data?.attributes?.name || "未分类", href: `/category/${category?.data?.attributes?.slug}` }, { label: p?.name || "商品详情", href: `/product/${slug}`, isCurrent: true } ]; return ( <div className="w-full md:py-12 relative"> <Wrapper> <div className="flex flex-col lg:flex-row md:px-10 md:gap-[50px] lg:gap-[20px] md:mt-10"> {/* 左侧商品轮播 */} <div className="w-full md:w-auto flex-[1.5] max-[350px] lg:max-w-full mx-auto lg:mx-0"> <ProductDetailsCarousel images={p.image.data} /> </div> {/* 右侧商品信息 */} <div className="flex-[1] py-3"> {/* 面包屑组件 */} <Breadcrumbs items={breadcrumbItems} /> {/* 原有商品标题等内容 */} <div className="text-sm md:text-xl lg:text-2xl font-semibold mb-2"> {p.name} </div> {/* ... 保留原有其他代码 */} </div> </div> {/* ... 保留原有弹窗等代码 */} </Wrapper> </div> ); };
4. 清理无效代码
删除原有useEffect中无效的toast提示代码:
// 删除这段无效代码 // useEffect(() => { // const categoryName = category?.data?.[0]?.attributes?.name; // if (categoryName) { // toast.toast; // success(`You are viewing: ${categoryName}`, { // position: "bottom-center", // }); // } // }, [category]);
内容的提问来源于stack exchange,提问作者fumei mai
相关产品推荐
相关产品推荐

