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

如何为NextUI NavBarItem设置isActive状态?

解决NextUI导航栏高亮当前页面的问题

核心问题

你之前用useRouter出现白屏,是因为Next.js 13+的App Router中,客户端组件需要从next/navigation导入usePathname,而非next/router的useRouter——后者是旧版Pages Router的API,和App Router不兼容。

可行解决方案

按以下步骤修改组件即可实现高亮:

  1. 替换路由API
    删除旧的useRouter导入,换成App Router的usePathname:
import { usePathname } from "next/navigation";
  1. 统一管理菜单数据
    把纯文本的menuItems改成包含标题和对应路径的数组,避免重复硬编码:
const menuItems = [
  { title: "Home", path: "/" },
  { title: "Features", path: "/features" },
  { title: "About Us", path: "/about-us" },
  { title: "Investing Framework", path: "/investing-framework" },
];
  1. 动态判断激活状态
    在组件中获取当前路径,给每个导航项绑定isActive属性,触发NextUI的高亮样式:
const pathname = usePathname();
  1. 修复移动端菜单链接
    把移动端菜单的href="#"改成对应页面的真实路径,确保跳转正常。

修改后的完整组件代码

"use client";

import { AcmeIcon } from "@/components/icons/Brands";
import { cn } from "@/utils/nextui/cn";
import { Button } from "@nextui-org/button";
import { Link } from "@nextui-org/link";
import type { NavbarProps } from "@nextui-org/navbar";
import {
  Navbar,
  NavbarBrand,
  NavbarContent,
  NavbarItem,
  NavbarMenu,
  NavbarMenuItem,
  NavbarMenuToggle,
} from "@nextui-org/navbar";
import { usePathname } from "next/navigation";
import React from "react";

const menuItems = [
  { title: "Home", path: "/" },
  { title: "Features", path: "/features" },
  { title: "About Us", path: "/about-us" },
  { title: "Investing Framework", path: "/investing-framework" },
];

export default function Component(props: NavbarProps) {
  const [isMenuOpen, setIsMenuOpen] = React.useState(false);
  const pathname = usePathname();

  return (
    <Navbar
      {...props}
      isBordered
      classNames={{
        base: cn("border-default-100", {
          "bg-default-200/50 dark:bg-default-100/50": isMenuOpen,
        }),
        wrapper: "w-full justify-center bg-transparent",
        item: [
          "flex",
          "relative",
          "h-full",
          "items-center",
          "data-[active=true]:after:content-['']",
          "data-[active=true]:after:absolute",
          "data-[active=true]:after:bottom-0",
          "data-[active=true]:after:left-0",
          "data-[active=true]:after:right-0",
          "data-[active=true]:after:h-[2px]",
          "data-[active=true]:after:rounded-[2px]",
          "data-[active=true]:after:bg-secondary",
        ],
      }}
      height="60px"
      isMenuOpen={isMenuOpen}
      onMenuOpenChange={setIsMenuOpen}
    >
      <NavbarMenuToggle className="text-default-400 md:hidden" />

      <NavbarBrand>
        <div className="rounded-full bg-foreground text-background">
          <AcmeIcon size={34} />
        </div>
        <span className="ml-2 font-medium bg-clip-text text-transparent bg-gradient-to-r from-purple-400 via-pink-500 to-red-500">humblFINANCE</span>
      </NavbarBrand>
      <NavbarContent
        className="hidden h-11 gap-4 rounded-full border-small border-default-200/20 bg-background/60 px-4 shadow-medium backdrop-blur-md backdrop-saturate-150 md:flex dark:bg-default-100/50"
        justify="center"
      >
        {menuItems.map((item) => (
          <NavbarItem key={item.path} isActive={pathname === item.path}>
            <Link className="text-default-500" href={item.path} size="sm">
              {item.title}
            </Link>
          </NavbarItem>
        ))}
      </NavbarContent>
      <NavbarContent justify="end">
        <NavbarItem className="ml-2 !flex gap-2">
          <Button
            className="bg-default-100 text-default-700 sm:bg-transparent sm:text-default-500"
            radius="full"
            variant="light"
          >
            Login
          </Button>
          <Button
            className="hidden border-small border-secondary-500/20 bg-secondary-500/10 text-secondary-800 sm:flex"
            color="secondary"
            radius="full"
            style={{
              boxShadow: "inset 0 0 4px #bf97ff70",
            }}
            variant="flat"
          >
            Get Started
          </Button>
        </NavbarItem>
      </NavbarContent>
      <NavbarMenu
        className="top-[calc(var(--navbar-height)_-_1px)] max-h-[70vh] bg-default-200/50 pt-6 shadow-medium backdrop-blur-md backdrop-saturate-150 dark:bg-default-100/50"
        motionProps={{
          initial: {opacity: 0, y: -20},
          animate: {opacity: 1, y: 0},
          exit: {opacity: 0, y: -20},
          transition: {
            ease: "easeInOut",
            duration: 0.2,
          },
        }}
      >
        {menuItems.map((item, index) => (
          <NavbarMenuItem key={`${item.title}-${index}`}>
            <Link 
              className={`w-full ${pathname === item.path ? "text-secondary font-medium" : "text-default-500"}`} 
              href={item.path} 
              size="md"
            >
              {item.title}
            </Link>
          </NavbarMenuItem>
        ))}
      </NavbarMenu>
    </Navbar>
  );
}

关键说明

  • usePathname会实时返回当前页面的路径,用来精准匹配导航项。
  • NavbarItem的isActive属性会自动触发你预先定义的底部下划线高亮样式。
  • 移动端菜单同步了路径判断,给当前页面的菜单项添加了文字高亮,可根据需求调整样式细节。

内容的提问来源于stack exchange,提问作者JJ Fantini

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 09:34:59