如何为NextUI NavBarItem设置isActive状态?
解决NextUI导航栏高亮当前页面的问题
核心问题
你之前用useRouter出现白屏,是因为Next.js 13+的App Router中,客户端组件需要从next/navigation导入usePathname,而非next/router的useRouter——后者是旧版Pages Router的API,和App Router不兼容。
可行解决方案
按以下步骤修改组件即可实现高亮:
- 替换路由API
删除旧的useRouter导入,换成App Router的usePathname:
import { usePathname } from "next/navigation";
- 统一管理菜单数据
把纯文本的menuItems改成包含标题和对应路径的数组,避免重复硬编码:
const menuItems = [ { title: "Home", path: "/" }, { title: "Features", path: "/features" }, { title: "About Us", path: "/about-us" }, { title: "Investing Framework", path: "/investing-framework" }, ];
- 动态判断激活状态
在组件中获取当前路径,给每个导航项绑定isActive属性,触发NextUI的高亮样式:
const pathname = usePathname();
- 修复移动端菜单链接
把移动端菜单的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
相关产品推荐
相关产品推荐

