在 Next.js 中为导航链接添加活动类

rea*_*ing 5 javascript frontend reactjs next.js

我正在使用Next.js,并且希望在链接到的页面与 url 匹配时将活动类添加到导航链接。但我也希望当 url 比页面更深时它处于活动状态。

例如,导航链接对于以下/register内容将是“活动的”:

  • /register
  • /register/sign-up

Luk*_*lor 7

这是NavLink我为 Next.js 编写的组件。它具有相同的 APILink,但添加了两个 props:

\n
    \n
  • 一个activeClassName匹配时将应用于
  • \n
  • (选修的)exact - 防止匹配 \xe2\x80\x9cdeeper\xe2\x80\x9d 路由)
  • \n
\n
import React from \'react\';\nimport Link from \'next/link\';\nimport { useRouter } from \'next/router\';\n\nexport default function NavLink({ href, as, exact, activeClassName, children, ...props }) {\n  const { asPath } = useRouter();\n  // Normalize and split paths into their segments\n  const segment = (p) => new URL(p, \'http://example.com\').pathname.split(\'/\').filter(s => s);\n  const currentPath = segment(asPath);\n  const targetPath = segment(as || href);\n  // The route is active if all of the following are true:\n  //   1. There are at least as many segments in the current route as in the destination route\n  //   2. The current route matches the destination route\n  //   3. If we\'re in \xe2\x80\x9cexact" mode, there are no extra path segments at the end\n  const isActive = currentPath.length >= targetPath.length\n    && targetPath.every((p, i) => currentPath[i] === p)\n    && (!exact || targetPath.length === currentPath.length);\n\n  const child = React.Children.only(children);\n  const className = ((child.props.className || \'\') + \' \' + (isActive ? activeClassName : \'\')).trim();\n\n  return (\n    <Link href={href} as={as} {...props}>\n      {React.cloneElement(child, { className })}\n    </Link>\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n

通过依赖来自path-to-regexp,该模块已经是 Next.js 的依赖项:

\n
import React from \'react\';\nimport Link from \'next/link\';\nimport { useRouter } from \'next/router\';\nimport { pathToRegexp } from \'path-to-regexp\';\n\nexport default function NavLink({ href, as, exact, activeClassName, children, ...props }) {\n  const { asPath } = useRouter();\n  const isActive = pathToRegexp(as || href, [], { sensitive: true, end: !!exact }).test(asPath);\n\n  const child = React.Children.only(children);\n  const className = ((child.props.className || \'\') + \' \' + (isActive ? activeClassName : \'\')).trim();\n\n  return (\n    <Link href={href} as={as} {...props}>\n      {React.cloneElement(child, { className })}\n    </Link>\n  );\n}\n
Run Code Online (Sandbox Code Playgroud)\n