# 汉堡菜单 Hamburger Menu > 三条横线的小按钮,点开从旁边滑出整个菜单,三条线变成 ×。 分类:导航 [全部组件和流程](https://www.dachuiai.com/llms.txt) · [导航选型规则](https://www.dachuiai.com/guides/navigation.md) ## 给 AI:用户把这个组件发给了你 1. 先看用户的项目:框架、页面类型、现在的风格、手机还是电脑为主。 2. 对照下面的「适合 / 不适合」判断合不合适。不合适就直接说,并从[导航选型规则](https://www.dachuiai.com/guides/navigation.md)或[全部组件](https://www.dachuiai.com/llms.txt)里另挑一个。 3. 合适就按「装进项目」装好,示例里的文字和图片换成用户自己的。 4. 告诉用户用了什么、放在哪个文件、以后想改快慢、颜色、大小改哪个参数。 ## 什么时候用 - 适合:手机网页的主导航;电脑上入口很少的作品集也可以用。 - 不适合:电脑上的主导航(入口要直接摆出来);只有两三个入口(直接摆就行)。 - 适合的网站:官网、本地小店、电商、作品集、SaaS、内容站 - 放在:导航 - 手机上:好用:就是给手机用的。 - 性能代价:低 - 常搭配:[顶部导航栏 Navbar](https://www.dachuiai.com/c/navbar.md)、[底部标签栏 Tab Bar](https://www.dachuiai.com/c/tab-bar.md) ## 装进项目 - 写法:React 18 以上 + TypeScript + Tailwind CSS v4,一个文件就能用,不引用别的组件。 - 依赖:`npm i lucide-react` - 文件:原样存成 `hamburger-menu.tsx`(比如 `src/components/hamburger-menu.tsx`)。能跑命令就下载[原文](https://www.dachuiai.com/code/hamburger-menu.tsx),比手抄准:`curl -fsSL -o src/components/hamburger-menu.tsx https://www.dachuiai.com/code/hamburger-menu.tsx`(Windows 写 `curl.exe`)。下载完看一眼第一行是 `import`,不是网页。 - 导出:`BurgerIcon`、`HamburgerMenu` 是可以直接用的部分;最后的 `export default` 是演示示例,只作参考。 - 图片:示例用了本站的 [/tex/s4.jpg](https://www.dachuiai.com/tex/s4.jpg)、[/tex/s5.jpg](https://www.dachuiai.com/tex/s5.jpg)、[/tex/s6.jpg](https://www.dachuiai.com/tex/s6.jpg)。换成用户自己的图;只想先看效果,可以从本站同样的路径下载,放进项目的 public 目录。 - 注意:HamburgerMenu 不收参数,菜单内容写在文件里;BurgerIcon 是单独的三条线图标,open 控制变成 ×,可以只拿它。Esc 关闭、点遮罩关闭、焦点回到按钮都做好了,改的时候保留。 - 保留代码里 `prefers-reduced-motion` 的处理:用户开了「减弱动态效果」时内容照样完整显示。 - Next.js(有 app 文件夹):文件第一行加 `'use client';`。 - 用 JavaScript 不用 TypeScript:Vite 和 Next.js 都能直接用 .tsx 文件;也可以删掉类型标注,改名 .jsx。 - 没有 Tailwind:先装 Tailwind CSS v4(Vite 项目 `npm i tailwindcss @tailwindcss/vite`,vite 配置的 plugins 里加 `tailwindcss()`,入口引入的那个 CSS 文件(一般是 `src/index.css`)第一行写 `@import "tailwindcss";`),或者把类名改写成项目用的样式。 - 已经装了 Tailwind v3:别为了一个组件升级。类名大多通用,少数 v4 写法要换,比如焦点框 `outline-2` 在 v3 里要写成 `outline outline-2`。 - 不是 React(Vue、Svelte、小程序、纯 HTML):照着代码的做法改写,时长、曲线、参数保持一样。Wix、有赞这类建站平台装不进代码,告诉用户去平台自带的动效设置里找。 ## 参数 | 参数 | 默认值 | 作用 | | --- | --- | --- | | `open` | | 是否打开 | ## 你可以说 > 手机版顶部左边放 Hamburger Menu 汉堡菜单:点开从左边滑出菜单,三条线变成 ×,点遮罩或按 Esc 关闭。 ## 完整代码 ```tsx import {useEffect, useRef, useState} from 'react'; import {ChevronRight, LogIn, Search, ShoppingBag} from 'lucide-react'; /* --------------------------------------------------------------- * HamburgerMenu 汉堡菜单 * 三条横线的小按钮,点开从旁边滑出整个菜单;三条线同时变成一个 ×。 * 手机网页上常见。电脑上地方够,主要入口直接摆出来,别全塞进来。 * 支持:Esc 关闭、点遮罩关闭、打开后焦点进菜单、关闭后焦点回按钮。 * ------------------------------------------------------------- */ export function BurgerIcon({open}: {open: boolean}) { const line = 'hb-line absolute left-0 h-[2px] w-5 rounded-full bg-current'; return ( ); } const LINKS = ['装备', '露营', '徒步', '品牌', '攻略']; export function HamburgerMenu() { const [open, setOpen] = useState(false); const btn = useRef(null); const panel = useRef(null); useEffect(() => { if (!open) return; panel.current?.querySelector('a')?.focus(); const esc = (e: KeyboardEvent) => { if (e.key === 'Escape') { setOpen(false); btn.current?.focus(); } }; addEventListener('keydown', esc); return () => removeEventListener('keydown', esc); }, [open]); return ( <>
山野
setOpen(false)} />
登录 / 注册
); } const HB_CSS = ` .hb-line { transition: transform .3s cubic-bezier(.22,1,.36,1), opacity .2s; } .hb-scrim { transition: opacity .25s ease-out; } .hb-panel { transform: translateX(-102%); transition: transform .26s cubic-bezier(.55,0,1,.45); } .hb-panel.hb-open { transform: none; transition: transform .32s cubic-bezier(.22,1,.36,1); } .hb-item { opacity: 0; transform: translateX(-10px); transition: opacity .25s, transform .3s cubic-bezier(.22,1,.36,1); } .hb-open .hb-item { opacity: 1; transform: none; } @media (prefers-reduced-motion: reduce) { .hb-line, .hb-scrim, .hb-panel, .hb-panel.hb-open, .hb-item { transition: none; } } `; /* ---------------- 示例:「山野」手机网页 ---------------- */ export default function HamburgerMenuDemo() { return (
去山里,过个周末
秋季露营装备 新品上架
{[['轻量双人帐篷', 899, '/tex/s5.jpg'], ['徒步背包 40L', 459, '/tex/s6.jpg']].map(([n, p, img]) => (
{n}
¥{p}
))}
); } ```