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

Next.js搭配Tailwind的布局中如何为侧边栏菜单添加Heroicons图标

Next.js侧边栏集成Heroicons实现方案

你现有代码需要先修正导入错误,再调整菜单项渲染逻辑即可,步骤如下:

1. 修正Heroicons导入

你当前的图标导入写法有误,@heroicons/react/outline是图标库的模块入口,不能直接作为默认组件导入,需要按需引入具体图标:

// 原错误写法:import HomeIcon from "@heroicons/react/outline";
// 按需引入所有菜单需要的图标,v1版本图标带Icon后缀
import { HomeIcon, UserIcon, MailIcon } from "@heroicons/react/outline";

如果你使用的是Heroicons v2版本,outline图标导入路径为@heroicons/react/24/outline,图标名去掉了Icon后缀,比如首页图标对应Home,按需调整即可。

2. 调整菜单项配置

推荐在menuItems中传入图标组件引用而非JSX实例,减少不必要的重渲染:

const menuItems = [
  {
    href: "/",
    title: "Home",
    icon: HomeIcon,
  },
  {
    href: "/about",
    title: "About",
    icon: UserIcon,
  },
  {
    href: "/contact",
    title: "Contact",
    icon: MailIcon,
  },
];

如果你之前已经按icon: <HomeIcon />的写法传入JSX也可以正常运行,仅需要调整后续渲染写法即可。

3. 修改菜单项渲染逻辑

遍历菜单项时解构出icon字段,在导航链接内渲染图标,同时给链接标签加对齐、间距类,给图标加尺寸类即可:

{menuItems.map(({ href, title, icon: Icon }) => (
  <li className="m-2" key={title}>
    <Link href={href}>
      <a
        className={`flex items-center gap-2 p-2 bg-black text-white rounded hover:bg-red-600 cursor-pointer ${
          router.asPath === href && "bg-black text-red-600"
        }`}
      >
        {/* 传组件引用时直接作为组件渲染,设置统一图标尺寸 */}
        <Icon className="w-5 h-5" />
        {title}
      </a>
    </Link>
  </li>
))}

如果是直接传入JSX实例的写法,把<Icon className="w-5 h-5" />替换成{icon}即可,注意要给传入的JSX图标提前加上w-5 h-5的尺寸类,避免图标撑满容器。

完整修改后的Layout代码

import Link from "next/link";
import { useRouter } from "next/router";
import { HomeIcon, UserIcon, MailIcon } from "@heroicons/react/outline";

export default function Layout({ children }) {
  const router = useRouter();

  const menuItems = [
    {
      href: "/",
      title: "Home",
      icon: HomeIcon,
    },
    {
      href: "/about",
      title: "About",
      icon: UserIcon,
    },
    {
      href: "/contact",
      title: "Contact",
      icon: MailIcon,
    },
  ];

  return (
    <div className="min-h-screen flex flex-col">
      <header className="bg-white sticky top-0 h-14 flex justify-center items-center font-semibold uppercase">
        Next.js sidebar menu
      </header>
      <div className="flex flex-col md:flex-row flex-1">
        <aside className="bg-black w-full md:w-60">
          <nav>
            <ul>
              {menuItems.map(({ href, title, icon: Icon }) => (
                <li className="m-2" key={title}>
                  <Link href={href}>
                    <a
                      className={`flex items-center gap-2 p-2 bg-black text-white rounded hover:bg-red-600 cursor-pointer ${
                        router.asPath === href && "bg-black text-red-600"
                      }`}
                    >
                      <Icon className="w-5 h-5" />
                      {title}
                    </a>
                  </Link>
                </li>
              ))}
            </ul>
          </nav>
        </aside>
        <main className="flex-1">{children}</main>
      </div>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:36:20