【问题标题】:Breadcrumbs and NextJS面包屑和 NextJS
【发布时间】:2020-10-26 16:32:04
【问题描述】:

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

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

我需要你的帮助...

【问题讨论】:

  • 即使我正在寻找这个答案,如果您找到了上述查询的答案,请发布答案。我会接受的。

标签: reactjs next.js breadcrumbs


【解决方案1】:

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

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

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;

【讨论】:

    【解决方案2】:

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

    pages/example.jsx

    export default function Page() {
      return <>
        <BreadCrumbs />
        <h1>My Page</h1>
      </>
    }
    

    组件/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;
    }
    

    渲染的面包屑

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

    【讨论】:

      【解决方案3】:

      我曾想过使用 nextjs 面包屑,但我无法将其样式与 antd (Ant Desing) 对齐。并且想使用 antd 提供的默认面包屑组件,因此,返回一些使用 next js 路由器和一些 js 块的自己的简单组件。

      const router = useRouter();
      let routes= router.route.split('/');
      let str='';
      let hlinks=[];
      routes.forEach((i,index,arr)=>{
          if(i.charAt(0)=='[')
          {
              i=i.slice(1);
              i=i.slice(0, i.length - 1);
              console.log(i)
              arr[index]=router.query[i];
          }
          str=str+arr[index]+'/';
          hlinks.push(str);
      });
      console.log(hlinks);
      console.log(routes);
      

      【讨论】:

        【解决方案4】:
            const router = useRouter()
            const linkPath = router.asPath.split('/');
            linkPath.shift();
        
            const pathArray = linkPath.map((path, i) => {
                return { breadcrumb: path, href: '/' + linkPath.slice(0, i + 1).join('/') };
            });
            console.log(pathArray)
        

        【讨论】:

        • 不错的解决方案。如何在此处添加首页路由?
        • 您需要“手动”添加它,因为您的主页有“/”网址。因此,当您创建组件以显示 pathArray 时,您只需在 开头添加主页
        【解决方案5】:

        安装

        yarn add nextjs-antd-breadcrumbs
        

        用法

        该组件需要在 Next.js 中使用,并且不能在普通 React 中使用。 它将始终根据下一个路由器的当前路径显示动态面包屑导航。

        import React from 'react';
        import Breadcrumbs from 'nextjs-antd-breadcrumbs';
        
        const Example = () => {
          return <Breadcrumbs rootLabel="Home" omitRootLabel={false}/>;
        };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多