ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RSuite Sidenav 侧边导航组件基础用法与实践指南

RSuite Sidenav 侧边导航组件基础用法与实践指南 前端UI组件【免费下载链接】rsuite A suite of React components .项目地址https://gitcode.com/gh_mirrors/rs/rsuite点击查看免费下载Sidenav 是 RSuite 中用于搭建页面侧边栏Sidebar导航的组件本质上是Nav组件面向侧边栏场景的封装它天然支持图标菜单项、可折叠子菜单、展开/收起动画、多种外观主题以及与页面整体布局的配合。本文以 Sidenav 的基础示例为起点结合本仓库中该组件的完整 API 文档与源码实现逐步带你掌握从一个最简单的侧边导航到带分组、徽标、可折叠、可出现在弹窗中的完整侧边栏的全部实践要点。阅读本文后你将能够独立搭建一个带图标与多级菜单的侧边导航通过受控属性实现展开/收起熟练使用Sidenav.Header、Sidenav.Footer、Sidenav.GroupLabel、Sidenav.Toggle等子组件组合出完整的后台管理布局。1. Sidenav 是什么面向侧边栏的 Nav 封装在 RSuite 官方文档见 docs/pages/components/sidenav/en-US/index.md中Sidenav 的定义是一句话An encapsulation of the Nav for the sidebar of the page.即针对页面侧边栏场景封装的Nav。这意味着它与Nav共享同一套菜单语义Nav.Item菜单项、Nav.Menu子菜单、eventKey事件键、activeKey激活项等同时额外承担了侧边栏特有的职责整体展开/收起通过expanded属性控制整条侧边栏的宽窄切换并带有 300ms 的折叠动画外观主题提供default、inverse、subtle三种视觉外观子菜单展开状态管理通过openKeys/defaultOpenKeys管理哪些子菜单处于展开状态。从源码看Sidenav 由 6 个部分组合而成src/Sidenav/Sidenav.tsx 中的Subcomponents常量定义了挂载在Sidenav上的静态子组件const Subcomponents { Header: SidenavHeader, Body: SidenavBody, Footer: SidenavFooter, GroupLabel: SidenavGroupLabel, Toggle: SidenavToggle };也就是说Sidenav.Header、Sidenav.Body、Sidenav.Footer、Sidenav.GroupLabel、Sidenav.Toggle都是Sidenav的组成部分渲染结构通常为Sidenav Sidenav.Header / ← Logo、搜索框等 Sidenav.Body / ← 核心导航菜单Nav Sidenav.Footer / ← 折叠按钮等 /Sidenav2. 基础示例五分钟搭建一个侧边导航Sidenav 的基础用法文档位于 docs/pages/components/sidenav/fragments/basic.md其核心代码完整如下已补充注释import DashboardIcon from rsuite/icons/Dashboard; import PeoplesIcon from rsuite/icons/Peoples; import SettingIcon from rsuite/icons/Setting; import PieChartIcon from rsuite/icons/PieChart; import DataAuthorizeIcon from rsuite/icons/DataAuthorize; import { Sidenav, Nav } from rsuite; const App () ( // w 控制侧边栏宽度等价于 width: 240px Sidenav w{240} {/* Body 是导航菜单的容器 */} Sidenav.Body {/* 菜单本体使用 Nav 组织 */} Nav Nav.Item icon{DashboardIcon /}Overview/Nav.Item Nav.Item icon{PeoplesIcon /}Customers/Nav.Item Nav.Item icon{PieChartIcon /}Analytics/Nav.Item Nav.Item icon{DataAuthorizeIcon /}Security/Nav.Item Nav.Item icon{SettingIcon /}Settings/Nav.Item /Nav /Sidenav.Body /Sidenav ); ReactDOM.render(App /, document.getElementById(root));这段代码的关键点逐条拆解图标来自独立的rsuite/icons包DashboardIcon、PeoplesIcon、PieChartIcon、DataAuthorizeIcon、SettingIcon均从rsuite/icons导入而不是从rsuite主包导入。图标以icon{DashboardIcon /}的形式作为Nav.Item的icon属性传入渲染在菜单文字左侧。w{240}设置宽度Sidenav 的根元素基于 RSuite 内部的Box组件实现因此继承了Box的尺寸属性。w是width的简写等价于width: 240px。这一写法在仓库多个示例如basic.md、submenu.md、header.md中反复使用是侧边栏的标准宽度设置方式。结构约定Sidenav必须包裹Sidenav.BodyBody内部放Nav导航内容由Nav.Item平铺。这是最精简、最常见的侧边导航形态。文档示例的运行方式文档代码块以ReactDOM.render(...)结尾这是 RSuite 文档站演示环境的写法在实际项目中你只需要在自己的入口处正常挂载App /即可写法与本示例的结构完全一致。从源码看src/Sidenav/Sidenav.tsx 中 Sidenav 根元素的默认渲染为as nav, // 默认渲染为 nav 元素 classPrefix sidenav, // CSS 类名前缀如 rs-sidenav appearance default, expanded true即 Sidenav 默认就是一个展开状态的、语义化的nav元素根节点类名为rs-sidenav。这一点在 src/Sidenav/test/Sidenav.spec.tsx 的测试中也有对应断言expect(container.firstChild).to.have.class(rs-sidenav)。3. 组件结构与子组件职责Sidenav 的完整结构由官方文档 docs/pages/components/sidenav/en-US/index.md 的Examples章节给出除基础的Body Nav之外还包括子组件用途文档来源Sidenav.Header导航头部内容如 Logo、搜索框header.mdSidenav.Body导航主体承载Nav菜单basic.mdSidenav.Footer导航底部内容如折叠切换按钮footer.mdSidenav.GroupLabel导航分组标题需配合Nav.Item panel使用group.mdSidenav.Toggle展开/收起切换按钮需配合Sidenav.Footerfooter.md这些子组件通过 React Context 与根组件通信。src/Sidenav/SidenavContext.tsx 定义并在 src/Sidenav/Sidenav.tsx 中注入的上下文包含{ expanded, // 当前是否展开 activeKey, // 当前激活的菜单键 sidenav: true, // 标记处于 Sidenav 环境 openKeys: openKeys ?? [], // 当前展开的子菜单键 onOpenChange, // 菜单开合回调 onSelect // 菜单选择回调 }以Sidenav.Toggle为例src/Sidenav/SidenavToggle.tsx它内部通过useContext(SidenavContext)读取当前的expanded状态点击时调用onToggle?.(!expanded, event)通知外部切换状态同时渲染一个IconButton图标为ArrowLeftLineIcon并通过aria-label展开时为Collapse收起时为Expand保证可访问性。若Sidenav.Toggle被渲染在Sidenav之外源码中还会在控制台输出错误提示Sidenav.Toggle must be rendered within a Sidenav并返回null。4. 属性参考Props官方文档 docs/pages/components/sidenav/en-US/index.md 的 Props 章节完整收录了各组件的属性定义整理如下类型与默认值均以文档为准4.1Sidenav属性类型默认值说明appearancedefault \| inverse \| subtle(default)侧边导航的视觉外观asElementType(div)根组件的自定义元素类型源码实际默认渲染为navclassPrefixstring(sidenav)组件 CSS 类名前缀defaultOpenKeysstring[]初始展开的下拉菜单项键数组非受控expandedboolean(true)控制侧边导航的展开/收起状态onOpenChange(openKeys: string[], event) void菜单项展开状态变化时的回调openKeysstring[]受控模式下展开的下拉菜单项键数组4.2Sidenav.Header属性类型默认值说明asElementType(div)头部组件的自定义元素类型classPrefixstring(sidenav-header)头部组件 CSS 类名前缀4.3Sidenav.Body属性类型默认值说明asElementType(div)主体组件的自定义元素类型classPrefixstring(sidenav-body)主体组件 CSS 类名前缀4.4Sidenav.Footer属性类型默认值说明asElementType(div)底部组件的自定义元素类型classPrefixstring(sidenav-footer)底部组件 CSS 类名前缀4.5Sidenav.Toggle属性类型默认值说明asElementType(button)切换按钮的自定义元素类型classPrefixstring(sidenav-toggle)切换按钮 CSS 类名前缀expandedboolean控制切换按钮所对应的展开状态onToggle(expanded: boolean) void切换状态变化的回调4.6Sidenav.GroupLabel属性类型默认值说明asElementType(div)分组标签的自定义元素类型classPrefixstring(sidenav-group-label)分组标签 CSS 类名前缀需要说明的是Sidenav.Toggle与Sidenav.GroupLabel标注为 6.0.0 新增文档中以![][6.0.0]标记。Sidenav根组件上的activeKey与onSelect在文档中被标记为弃用deprecated官方建议改用Nav上的activeKey与onSelect这一点在源码注释src/Sidenav/Sidenav.tsx中也有明确标注。5. 源码级解析展开/收起与外观的底层实现5.1 展开/收起动画Sidenav的展开/收起并不是简单的条件渲染而是由 RSuite 的Transition组件驱动src/Sidenav/Sidenav.tsxTransition in{expanded} timeout{300} exitedClassName{prefix(collapse-out)} exitingClassName{prefix(collapse-out, collapsing)} enteredClassName{prefix(collapse-in)} enteringClassName{prefix(collapse-in, collapsing)} 即切换expanded时根元素会在rs-sidenav-collapse-in/rs-sidenav-collapse-out等类名之间过渡动画时长 300ms。相关样式定义于 src/Sidenav/styles/index.scss。测试用例 src/Sidenav/test/Sidenav.spec.tsx 中验证了expanded为true时根节点持有rs-sidenav-collapse-in类名。5.2 子菜单展开状态管理openKeys采用受控 非受控双模式源码使用useControlled(openKeysProp, defaultOpenKeys)——传入openKeys则为受控模式否则以defaultOpenKeys作为初始值自行维护状态。切换逻辑handleOpenChange的做法是若点击的eventKey已在展开列表中就将其移除收起否则追加展开然后调用onOpenChange通知外部const handleOpenChange useCallback((eventKey, event) { const find key shallowEqual(key, eventKey); const nextOpenKeys [...openKeys]; if (nextOpenKeys.some(find)) { remove(nextOpenKeys, find); } else { nextOpenKeys.push(eventKey); } setOpenKeys(nextOpenKeys); onOpenChange?.(nextOpenKeys, event); }, [onOpenChange, openKeys, setOpenKeys]);5.3 外观属性appearance的值default/inverse/subtle会被映射为根元素上的data-appearance属性源码data-appearance{appearance}最终由 SCSS 根据该属性切换配色。对应测试src/Sidenav/test/Sidenav.spec.tsx验证了appearancesubtle时根元素持有data-appearancesubtleappearanceinverse时持有data-appearanceinverse。官方文档还特别提示在高对比度主题high-contrast themes下三种外观渲染效果一致均等同于default外观。5.4 收起状态下的特殊行为当Sidenav收起expanded{false}时一些装饰性内容会被隐藏。测试 src/Sidenav/test/Sidenav.spec.tsx 中有明确断言收起状态下Nav.Item的panel内容不会渲染.rs-dropdown-item-panel不存在divider分割线也不会渲染.rs-dropdown-item-divider不存在。这一点在自定义面板与分割线场景中需要特别注意——收起后这些元素会暂时消失。6. 进阶一子菜单与受控展开/收起6.1 子菜单Sub Menu基础形态只有平铺菜单项。当导航层级变深时使用Nav.Menu组织子菜单并通过defaultOpenKeys指定初始展开的菜单键。完整示例见 submenu.mdSidenav defaultOpenKeys{[3, 4]} w{240} Sidenav.Body Nav Nav.Item eventKey1 icon{DashboardIcon /}Overview/Nav.Item Nav.Menu eventKey2 titleCustomers icon{PeoplesIcon /} Nav.Item eventKey2-1Users/Nav.Item Nav.Item eventKey2-2Groups/Nav.Item /Nav.Menu Nav.Menu eventKey3 titleAnalytics icon{PieChartIcon /} Nav.Item eventKey3-1Geo/Nav.Item Nav.Item eventKey3-2Devices/Nav.Item Nav.Item eventKey3-3Loyalty/Nav.Item Nav.Item eventKey3-4Visit Depth/Nav.Item /Nav.Menu {/* ...更多 Nav.Menu */} /Nav /Sidenav.Body /Sidenav这里eventKey承担两种职责Nav.Menu的eventKey用于标识子菜单分组也是openKeys的取值Nav.Item的eventKey用于标识具体菜单项也是activeKey的取值。6.2 受控展开/收起Controlled Expand and Collapse当需要用一个外部开关如Toggle或底部按钮整体收起侧边栏时将expanded改为受控模式。完整示例见 collapsed.md核心骨架如下const [expanded, setExpanded] React.useState(false); const [activeKey, setActiveKey] React.useState(1); Box w{240} {/* 受控展开/收起开关 */} Toggle onChange{setExpanded} checked{expanded} checkedChildrenExpand unCheckedChildrenCollapse / Sidenav expanded{expanded} defaultOpenKeys{[3, 4]} Sidenav.Body Nav activeKey{activeKey} onSelect{setActiveKey} {/* Nav.Item 与 Nav.Menu 内容同前 */} /Nav /Sidenav.Body Sidenav.Footer Sidenav.Toggle onToggle{setExpanded} / /Sidenav.Footer /Sidenav /Box要点expanded由外部 state 完全控制Sidenav.Toggle.onToggle{setExpanded}与Toggle.onChange{setExpanded}都可以驱动状态这是受控组件 子组件的经典组合Sidenav.Toggle并不自己持有状态而是把反相后的值通过onToggle抛给父级源码见 src/Sidenav/SidenavToggle.tsx 的onToggle?.(!expanded, event)Nav自身的激活态也可以通过activeKeyonSelect完全受控。6.3 外观切换Appearanceappearance三种取值的对比示例见 appearance.md。示例中封装了一个CustomSidenav组件接收appearance、openKeys、expanded、onOpenChange、onExpand等属性从而把开合状态、展开菜单、激活项全部提升到父组件统一管理然后并排渲染三份侧边栏CustomSidenav ... / {/* default */} CustomSidenav ... appearanceinverse / {/* inverse深色/反色外观 */} CustomSidenav ... appearancesubtle / {/* subtle极简外观 */}实践中建议参考该示例将导航状态openKeys / activeKey / expanded统一收敛到页面级 state 中管理再通过onOpenChange、onSelect、onExpand回传更新这样多外观、多场景复用同一套数据模型非常方便。7. 进阶二Header、Footer、分组、分割线与徽标组合7.1 导航头部Logo 与搜索框Sidenav.Header用于放置 Logo、搜索框等固定内容示例见 header.mdconst Header () ( VStack p10px 10px 0 10px spacing{12} HStack SiProtondb size{32} / Brand /HStack InputGroup inside sizesm InputGroup.AddonSearchIcon //InputGroup.Addon Input typesearch placeholderSearch here... / /InputGroup /VStack ); Sidenav w{240} Sidenav.Header Header / /Sidenav.Header Sidenav.Body{/* Nav 菜单 */}/Sidenav.Body /Sidenav在收起场景下头部还可以自适应footer.md示例展示了根据expanded动态切换——收起时只居中显示品牌图标展开时显示品牌名 搜索框。这是做响应式侧边栏的常用手法。7.2 底部折叠按钮Sidenav.FooterSidenav.Toggle的组合见 footer.mdSidenav expanded{expanded} {/* Header / Body 内容同前 */} Sidenav.Footer Sidenav.Toggle onToggle{setExpanded} / /Sidenav.Footer /SidenavSidenav.Toggle渲染为一个图标按钮箭头图标点击后触发onToggle(!expanded)配合expanded受控属性完成整体收起/展开。这是后台管理系统中收起导航为图标栏的标准交互。7.3 分组标题Group Header当导航项很多时用Sidenav.GroupLabel做视觉分组。官方文档说明Sidenav.GroupLabel需要包裹在Nav.Item panel中才能生效见 group.mdNav.Item panel Sidenav.GroupLabelWorkspace/Sidenav.GroupLabel /Nav.Item Nav.Menu eventKey1 titleProjects icon{EventDetailIcon /} {/* ...子菜单项 */} /Nav.Menu Nav.Item panel Sidenav.GroupLabelManagement/Sidenav.GroupLabel /Nav.Item Nav.Menu eventKey4 titleTeam icon{PeoplesIcon /} {/* ...子菜单项 */} /Nav.Menu7.4 菜单内的分割线与面板利用Nav.Item的divider与panel属性可以在子菜单内部插入分割线和小标题面板示例见 divider-panel.mdNav.Menu eventKey3 titleAnalytics icon{PieChartIcon /} Nav.Item divider / Nav.Item panel Sidenav.GroupLabelReports/Sidenav.GroupLabel /Nav.Item Nav.Item eventKey3-1Geo/Nav.Item {/* ... */} /Nav.Menu7.5 徽标With Badge在菜单项右侧显示数量或状态时可将Badge与HStack结合放入Nav.Item内容区示例见 with-badge.mdconst NavItem ({ icon, children, badge }) ( Nav.Item icon{icon} HStack justifyContentspace-between style{{ flex: 1 }} {children} {badge} /HStack /Nav.Item ); NavItem icon{NoticeIcon /} badge{Badge content{15} /}Notification/NavItem NavItem icon{CalenderDateIcon /} badge{Badge contentnew coloryellow /}Schedule/NavItemBadge的content支持数字与字符串color可自定义徽标颜色。7.6 在弹窗中使用In ModalSidenav 不限于整页布局也可以嵌入Modal中形成弹窗内文件浏览器式的侧栏示例见 in-modal.mdModal overflow open{open} sizelg onClose{() setOpen(false)} dialogStyle{{ padding: 0 }} HStack alignItemsstretch Sidebar / {/* 内含 Sidenav w{200} defaultOpenKeys{[1, 2]} */} Modal.Body style{{ flex: 1, padding: 20 }} {/* 内容区 */} /Modal.Body /HStack /Modal8. 小结与适用前提何时使用 Sidenav页面级侧边导航、后台管理系统布局、需要整体收起/展开交互的导航栏以及弹窗内嵌侧栏等场景。它复用Nav的完整菜单能力多级子菜单、激活态、事件键因此与Nav的知识可以无缝衔接。状态管理建议expanded、openKeys、activeKey均可受控。菜单较多时建议将三者集中到页面级 state通过onOpenChange/onSelect/onToggle更新便于实现同一份状态、多套外观的复用。依赖说明示例中的图标均来自独立的rsuite/icons包如DashboardIcon、SettingIcon组件本体来自rsuite主包搜索框、输入组等使用了Input、InputGroup、HStack、VStack、Box、Toggle、Badge、Modal等 RSuite 内置组件。版本前提Sidenav.Toggle、Sidenav.GroupLabel为 6.0.0 起新增Sidenav根组件上的activeKey/onSelect已标记为弃用请改在Nav上使用。高对比度主题下appearance的三种外观渲染一致。源码可查组件的完整实现位于 src/Sidenav/核心逻辑见 Sidenav.tsx切换按钮见 SidenavToggle.tsx样式见 styles/index.scss行为验证测试见 test/Sidenav.spec.tsx完整文档与全部示例见 docs/pages/components/sidenav/en-US/index.md 及 docs/pages/components/sidenav/fragments/ 目录。赞分享前端UI组件【免费下载链接】rsuite A suite of React components .项目地址https://gitcode.com/gh_mirrors/rs/rsuite点击查看免费下载相关推荐RSuite Sidenav 组件完整指南构建可折叠、可定制、多级分组的页面侧边栏导航RSuite Sidenav 组件完整指南构建可折叠、可定制、多级分组的页面侧边栏导航 Sidenav 是 RSuite 中对页面侧边栏场景下的 Nav 导航前端UI组件rsuite Sidenav 侧导航中 divider 与 panel 属性实战用分割线与分组标签构建结构化导航菜单rsuite Sidenav 侧导航中 divider 与 panel 属性实战用分割线与分组标签构建结构化导航菜单 本文基于 rsuite 官方文档中Cu前端UI组件Base Web Side Navigation 侧边导航组件从基础用法到源码级剖析Base Web Side Navigation 侧边导航组件从基础用法到源码级剖析 侧边导航菜单Side Navigation是 Base Web 中用设计系统UI组件前端上一篇Windows 防休眠指南免管理员权限的免费轻量方案下一篇Hindsight 记忆备份与恢复完全指南4 步守住你的智能体记忆数据创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表