面包屑和 NextJS

jip*_*pay 6 breadcrumbs reactjs next.js

我想为我的 NextJS 应用程序制作面包屑,我想知道是否有好的或实用的方法来做到这一点?

我想通过 Ant Design,但是带有 React Router 的组件示例并不适合我。

我需要你的帮助,请...

Mar*_*nes 12

如果你使用 Next.js 路由系统,我建议你看看nextjs-breadcrumbs,它简单有效。

或者,如果您更喜欢编写自己的组件,请使用他们的代码作为参考。

import React, { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import Link from 'next/link';

const convertBreadcrumb = string => {
  return string
    .replace(/-/g, ' ')
    .replace(/oe/g, 'ö')
    .replace(/ae/g, 'ä')
    .replace(/ue/g, 'ü')
    .toUpperCase();
};

const Breadcrumbs = () => {
  const router = useRouter();
  const [breadcrumbs, setBreadcrumbs] = useState(null);

  useEffect(() => {
    if (router) {
      const linkPath = router.asPath.split('/');
      linkPath.shift();

      const pathArray = linkPath.map((path, i) => {
        return { breadcrumb: path, href: '/' + linkPath.slice(0, i + 1).join('/') };
      });

      setBreadcrumbs(pathArray);
    }
  }, [router]);

  if (!breadcrumbs) {
    return null;
  }

  return (
    <nav aria-label="breadcrumbs">
      <ol className="breadcrumb">
        <li>
          <a href="/">HOME</a>
        </li>
        {breadcrumbs.map((breadcrumb, i) => {
          return (
            <li key={breadcrumb.href}>
              <Link href={breadcrumb.href}>
                <a>
                  {convertBreadcrumb(breadcrumb.breadcrumb)}
                </a>
              </Link>
            </li>
          );
        })}
      </ol>
    </nav>
  );
};

export default Breadcrumbs;
Run Code Online (Sandbox Code Playgroud)


Ben*_*ing 5

这是我在 nextjs 中处理面包屑的方法,它使用 来router.asPath获取面包屑的链接,并使用router.route来获取标签(如果它存在于Route2LabelMap.

页面/example.jsx

export default function Page() {
  return <>
    <BreadCrumbs />
    <h1>My Page</h1>
  </>
}
Run Code Online (Sandbox Code Playgroud)

组件/BreadCrumbs.jsx

import Link from "next/link";
import { useRouter } from "next/router";
import React from "react";

/*
interface BreadCrumb {
  route: string;
  label: string;
  link: string;
}
*/

const Route2LabelMap = {
  "/": "Home",
  "/profile/[username]/barrels": "Your Barrels",
  "/barrels": "Barrel List",
  "/barrels/[barrel_id]": "Barrel",
  "/barrels/[barrel_id]/settings": "Settings",
};

export function BreadCrumbs() {
  const router = useRouter();

  const [crumbs, setCrumbs] = React.useState([]);

  React.useEffect(() => {
    const segmentsPath = router.asPath.split("/");
    const segmentsRoute = router.route.split("/");
    const crumbLinks = CombineAccumulatively(segmentsPath);
    const crumbLabels = CombineAccumulatively(segmentsRoute);

    const crumbs = crumbLinks.map((link, index) => {
      const route = crumbLabels[index];
      const crumb = {
        link: link,
        route: route,
        label: Route2LabelMap[route] || route,
      };
      return crumb;
    });
    setCrumbs(crumbs);

    console.log({
      router,
      segmentsPath,
      segmentsRoute,
      crumbLinks,
      crumbLabels,
      crumbs,
    });
  }, [router.route]);

  return (
    <div className="w-full flex gap-1">
      {crumbs.map((c, i) => {
        return (
          <div className="flex items-center gap-1" key={i}>
            {(i > 0) ? <div>{'>'}</div> : null}
            <div className={(i == (crumbs.length - 1) ? 'bg-blue-300 ' : 'bg-gray-300 ') + " px-2 py-1 rounded-xl"}>
              <Link href={c.link}>
                <a>{c.label}</a>
              </Link>
            </div>
          </div>
        );
      })}
    </div>
  );
}

function CombineAccumulatively(segments) {
  /* 
  when segments = ['1','2','3']
  returns ['1','1/2','1/2/3']
  */
  const links = segments.reduce((acc, cur, curIndex) => {
    const last = curIndex > 1 ? acc[curIndex - 1] : "";
    const newPath = last + "/" + cur;
    acc.push(newPath);
    return acc;
  }, []);
  return links;
}
Run Code Online (Sandbox Code Playgroud)

渲染的面包屑

在这种情况下,要么显示路线,要么显示标签(如果变量中存在标签) Route2LabelMap,就像“Your Barrels”那样。

在此输入图像描述