☰
Nuxt UI 的 DashboardSidebar 组件完全指南:可拖拽调整、可折叠的仪表盘侧边栏
2026/10/8 23:30:44 网站建设 项目流程
  • 前端
  • UI组件

【免费下载链接】ui

The Intuitive Vue UI Library powered by Reka UI & Tailwind CSS.

项目地址:https://gitcode.com/gh_mirrors/ui4/ui
点击查看免费下载

DashboardSidebar 是 Nuxt UI 中专门为仪表盘(Dashboard)布局设计的侧边栏组件,支持拖拽调整宽度、靠近边缘自动折叠、状态持久化,并与DashboardGroup、DashboardPanel、DashboardNavbar等组件深度集成。读完本文你将掌握其完整用法:如何在布局中接入、如何配置可调整/可折叠行为、如何用mode与插槽定制菜单与内容、如何通过v-model控制开合状态,以及其背后的持久化与底层实现原理。

组件定位:DashboardSidebar 与 Sidebar 的区别

在开始使用之前,需要先明确DashboardSidebar与普通 Sidebar 的适用场景。二者同名但定位完全不同:

  • DashboardSidebar专为仪表盘布局设计,核心能力是拖拽调整宽度(drag-to-resize)、状态持久化(state persistence)以及与DashboardGroup等仪表盘组件体系的集成,适合数据面板、管理后台这类需要可自由调节空间的场景;
  • Sidebar是独立的轻量侧边栏,适合聊天面板、设置页、普通导航等不需要拖拽调整的简单场景。

从源码看,DashboardSidebar的接口直接继承自useResizablecomposable 的尺寸相关属性(id、side、minSize、maxSize、defaultSize、resizable、collapsible、collapsedSize),见 src/runtime/components/DashboardSidebar.vue,这正是它与普通侧边栏的本质差异所在。

基本用法:嵌入 DashboardGroup 布局

DashboardSidebar必须放置在DashboardGroup的默认插槽中,由其提供共享的上下文(context)。一个典型的仪表盘布局文件如下:

<template> <UDashboardGroup> <UDashboardSidebar /> <slot /> </UDashboardGroup> </template>

⚠️注意单一根元素问题:当使用resizable属性时,该组件没有单一根元素(其模板会额外渲染拖拽手柄和菜单浮层)。如果项目使用了页面过渡动画(page transitions)或需要单一根节点的布局场景,请用容器包裹,例如<div class="flex flex-1">。

组件结构上支持三个区域插槽:

  • header、footer:用于自定义侧边栏的顶部与底部区域;
  • default:侧边栏主体内容;
  • body/content:用于自定义侧边栏菜单(menu)部分。

Props 全解析与默认值

DashboardSidebar的完整属性定义位于 src/runtime/components/DashboardSidebar.vue,下面是每个属性的含义与源码中的默认值:

属性类型默认值说明
side'left' \| 'right''left'侧边栏渲染在哪一侧
mode'modal' \| 'slideover' \| 'drawer''slideover'侧边栏菜单(移动端浮层)的呈现模式
menu取决于mode的组件 Props—传递给菜单组件的属性,随mode自适应
toggleboolean \| ButtonPropstrue是否显示移动端打开按钮,可传Button组件属性自定义
toggleSide'left' \| 'right''left'切换按钮的位置
autoClosebooleantrue路由变化时是否自动关闭侧边栏
minSizenumber10最小尺寸
maxSizenumber20最大尺寸
defaultSizenumber15默认尺寸
resizablebooleanfalse是否允许拖拽调整
collapsiblebooleanfalse是否允许拖到边缘时折叠
collapsedSizenumber0折叠后的尺寸
idstringuseId()唯一标识,用于持久化键名与无障碍关联
open/collapsedbooleanfalse可通过v-model双向绑定控制的状态

其中minSize、maxSize、defaultSize默认值(10 / 20 / 15)是百分比含义(详见下文「Size」一节),且resizable与collapsible默认都是关闭的,需要显式开启。

持久化存储由 DashboardGroup 决定

侧边栏的状态(尺寸、折叠与否等)会保存到存储中,而存储方式由DashboardGroup的storage与storage-key属性决定:

DashboardGroup 属性默认值说明
storage'cookie'存储介质,可选'cookie'或'local'(localStorage)
storageKey'dashboard'存储键名前缀
persistenttrue是否持久化尺寸
unit'%'尺寸单位,可选'%'、'rem'、'px'

对应源码见 src/runtime/components/DashboardGroup.vue 与useResizable的存储逻辑 src/runtime/composables/useResizable.ts:当persistent开启且组件可调整或可折叠时,cookie模式使用useCookie、local模式使用useStorage;关闭持久化时则退化为普通响应式ref。

Toggle 按钮与自适应性

toggle属性控制移动端用于打开侧边栏的按钮。传true时使用默认的DashboardSidebarToggle组件;也可以传入一个对象,此时对象中的任意属性都会透传给底层的 Button 组件,例如:

<UDashboardSidebar :toggle="{ color: 'primary', variant: 'solid' }" />

toggle-side属性则控制该按钮渲染在左侧还是右侧(默认left)。从实现看,按钮的图标会根据当前开合状态切换(打开时为close图标,关闭时为menu图标),并带有相应的aria-label,见 src/runtime/components/DashboardSidebarToggle.vue。

Resizable:开启拖拽调整

给侧边栏加上resizable属性即可让用户通过拖拽边缘手柄来调整宽度:

<UDashboardSidebar resizable :min-size="22" :default-size="35" :max-size="40" />

开启后组件会在侧边栏的一侧渲染一个拖拽手柄(DashboardResizeHandle),并暴露resize-handle插槽供自定义。底层由useResizable实现完整的拖拽逻辑(src/runtime/composables/useResizable.ts):

  • 鼠标与触摸事件均被支持(onMouseDown/onTouchStart),通过监听全局mousemove/touchmove计算位移;
  • 拖拽过程中实时将新宽度写入size,并通过Math.min(maxSize, Math.max(minSize, newValue))钳制在minSize与maxSize之间;
  • 双击拖拽手柄会恢复为defaultSize(onDoubleClick,见 useResizable.ts);
  • 在RTL(从右到左)语言环境下,位移增量的方向会自动反转计算(useResizable.ts)。

Collapsible:拖到边缘自动折叠

配合resizable使用collapsible属性,可以让用户把侧边栏拖到屏幕边缘附近时自动折叠:

<UDashboardSidebar resizable collapsible :min-size="22" :default-size="35" :max-size="40" />

折叠判定的阈值在useResizable中实现:当拖拽计算出的新尺寸小于collapsedSize + 4时自动折叠(useResizable.ts);折叠后再拖拽或调大尺寸则会自动展开,并恢复折叠前的宽度(previousSize会被暂存,见 useResizable.ts)。

⚠️重要约束:DashboardSidebarCollapse 组件只有在侧边栏设置了collapsible时才有效,否则点击无效。

在插槽中感知折叠状态

折叠状态会通过插槽 props 暴露给header、default、footer插槽({ collapsed, collapse }),方便你在折叠后切换内容。例如可以在侧边栏折叠时只显示图标、隐藏文字。

Size:尺寸控制四件套

min-size、max-size、default-size与collapsed-size四个属性共同决定侧边栏的尺寸行为:

<UDashboardSidebar resizable collapsible :min-size="22" :default-size="35" :max-size="40" :collapsed-size="0" />

两点需要特别说明:

  1. 默认以百分比计算:文档示例中的35表示占据父容器宽度的 35%。如果需要改用rem或px,通过DashboardGroup的unit属性切换(见上文表格)。useResizable在rem模式下会读取根元素fontSize进行像素换算(useResizable.ts);
  2. collapsed-size默认是0,但主题为根节点设置了min-w-16(最小宽度 4rem),保证即使折叠到 0 也仍然能看到侧边栏的"残余"轮廓,避免完全消失(对应主题见 src/theme/dashboard-sidebar.ts)。

Side:切换侧边栏方向

side属性默认为left,改为right即可把侧边栏渲染到右侧:

<UDashboardSidebar side="right" resizable collapsible />

从主题源码可以观察到方向差异的处理:左侧侧边栏根节点带border-e border-default(右侧边框线),右侧侧边栏则没有(src/theme/dashboard-sidebar.ts);拖拽手柄也会根据side被渲染到对应的一侧。

Mode:侧边栏菜单的三种浮层模式

在移动端(小于lg断点),侧边栏会隐藏为浮层菜单,mode属性决定浮层的呈现方式,默认slideover:

  • modal:模态对话框(对应Modal组件),源码中会自动补上fullscreen: true, transition: false;
  • slideover:从左侧滑出(对应Slideover组件,自动补side: 'left');
  • drawer:抽屉式(对应Drawer组件)。

选择逻辑见 src/runtime/components/DashboardSidebar.vue:Menu是一个根据mode动态映射到USlideover/UModal/UDrawer的计算属性。

用menu属性定制浮层

menu属性用于向菜单组件透传属性,它会随mode的类型自适应(modal时是ModalProps、slideover时是SlideoverProps、drawer时是DrawerProps),并通过defu与mode自动注入的默认值合并(DashboardSidebar.vue)。例如:

<UDashboardSidebar mode="slideover" :menu="{ side: 'right' }" />

菜单区域的内容可以通过插槽定制:body插槽填充头部下方的菜单主体,content插槽则填充整个菜单。测试用例覆盖了三种mode的渲染(见 test/components/DashboardSidebar.spec.ts)。

提示:文档中的移动端示例之所以同时包含DashboardGroup、DashboardPanel与DashboardNavbar,是因为演示移动端效果需要完整的仪表盘容器。

Toggle 与 Toggle Side:移动端开合按钮

toggle与toggle-side配合用于移动端打开侧边栏浮层:

<UDashboardSidebar toggle toggle-side="right" />
  • toggle接受boolean或 Button 属性对象({ color: 'neutral', variant: 'ghost' }是默认观感);
  • toggle-side控制按钮在菜单头部中的位置,主题中右侧按钮会自动应用ms-auto推向最右(src/theme/dashboard-sidebar.ts)。

Examples:用 v-model 掌控开合与折叠状态

控制打开状态

通过open属性或v-model:open指令即可完全控制侧边栏的打开/关闭:

<UDashboardSidebar v-model:open="open" />

文档示例还演示了结合 defineShortcuts 注册键盘快捷键:按O键即可切换侧边栏的开合状态。

控制折叠状态

类似地,collapsed属性与v-model:collapsed指令用于控制折叠状态:

<UDashboardSidebar v-model:collapsed="collapsed" resizable collapsible />

示例中通过defineShortcuts注册了按C键切换折叠。从源码看,外部传入的collapsedref 会与内部useResizable的折叠状态双向同步:初始化时从存储恢复、运行时通过watch双向同步(useResizable.ts)。

深入底层:状态持久化、Context 与运行时钩子

持久化如何工作

DashboardSidebar的持久化键由storageKey(来自DashboardGroup,默认dashboard)加-sidebar-加id(或useId()生成的唯一 ID)拼接而成。每次尺寸或折叠状态变化都会写入存储,下次加载时自动恢复(DashboardSidebar.vue)。useResizable还做了防御性处理:如果读取到损坏的null存储值,会在写入时自动重建为默认值(useResizable.ts)。

Context 如何共享

DashboardGroup通过provideDashboardContext注入包含storage、storageKey、unit、sidebarOpen、sidebarCollapsed、toggleSidebar、collapseSidebar等字段的上下文(见 src/runtime/utils/dashboard.ts 与 src/runtime/components/DashboardGroup.vue)。DashboardSidebar、DashboardSidebarToggle、DashboardSidebarCollapse都通过useDashboard()消费这份上下文,从而实现跨组件联动。

Runtime Hooks

DashboardGroup将toggleSidebar与collapseSidebar封装为 Nuxt 运行时钩子调用:

  • dashboard:sidebar:toggle:切换打开状态;
  • dashboard:sidebar:collapse:设置折叠状态。

DashboardSidebar内部通过useRuntimeHook监听这两个钩子来同步自身状态(DashboardSidebar.vue),这为第三方扩展或命令式调用提供了统一的入口。

autoClose:路由变化自动关闭

autoClose默认为true,组件会监听route.fullPath,路由变化时自动关闭侧边栏(DashboardSidebar.vue)。在带路由跳转的导航场景下无需手动处理关闭逻辑;若侧边栏在非路由场景使用(例如纯状态面板),可将其关闭。

Slots 一览

组件共暴露 6 个插槽,完整签名见 DashboardSidebar.vue:

插槽作用插槽 Props
header侧边栏顶部区域collapsed,collapse(value)
default侧边栏主体collapsed,collapse(value)
footer侧边栏底部区域collapsed,collapse(value)
toggle自定义移动端切换按钮open,toggle(),ui
content自定义整个浮层菜单close?()
resize-handle自定义拖拽手柄onMouseDown,onTouchStart,onDoubleClick,ui

测试中已对全部 6 个插槽逐一做了快照渲染验证(test/components/DashboardSidebar.spec.ts)。

主题定制

组件的视觉样式统一由主题文件 src/theme/dashboard-sidebar.ts 定义,包含root、header、body、footer、toggle、handle、content、overlay等插槽类,并带有menu(浮层菜单下的内边距)与side两个变体。关键设计:

  • root:relative hidden lg:flex flex-col min-h-svh min-w-16 w-(--width) shrink-0—— 桌面端(lg以上)显示为 flex 纵向布局,宽度由 CSS 变量--width驱动(该变量由组件内联写入--width: ${size}${unit});
  • content/overlay:默认lg:hidden,即浮层菜单只在移动端出现。

与所有 Nuxt UI 组件一致,你可以通过ui属性或appConfig.ui.dashboardSidebar覆盖任意插槽样式。

质量保障:测试与无障碍

组件测试位于 test/components/DashboardSidebar.spec.ts,覆盖了:

  • 全部核心 Props(id、side、尺寸四件套、resizable、collapsible、三种mode、toggle开关与对象形式、toggleSide、ui定制等)的快照渲染;
  • 菜单对话框的无障碍标签:打开时对话框以本地化文案(如 "Open sidebar")作为aria-labelledby标题;
  • axe 无障碍自动检测:resizable + collapsible组合下零违规(DashboardSidebar.spec.ts)。

这保证了组件在复杂交互(拖拽、折叠、浮层)下仍符合可访问性要求。

总结

DashboardSidebar是构建可交互、可持久化仪表盘布局的核心组件:通过resizable/collapsible提供桌面端的拖拽与自动折叠体验,通过mode/menu/toggle提供移动端的浮层导航,通过DashboardGroup统一管理存储与单位,并通过v-model:open/v-model:collapsed与运行时钩子保持状态可控。结合useResizable的底层实现(RTL 适配、双击恢复、折叠阈值、存储防御)与完整的测试保障,它可以直接成为你下一个管理后台布局的可靠基础设施。

  • 前端
  • UI组件

【免费下载链接】ui

The Intuitive Vue UI Library powered by Reka UI & Tailwind CSS.

项目地址:https://gitcode.com/gh_mirrors/ui4/ui
点击查看免费下载
上一篇:Yaak API客户端插件依赖冲突:如何快速解决npm包版本兼容性问题
下一篇:Odysseus 对接 Claude Code 实战:作用域 API、能力开关与 Cookbook 模型服务调试闭环

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询