VitePress 默认主题侧边栏(Sidebar)配置完全指南:分组、多侧边栏、折叠与路径前缀
【免费下载链接】vitepressVite & Vue powered static site generator.项目地址: https://gitcode.com/gh_mirrors/vi/vitepress
侧边栏是 VitePress 文档站点的核心导航模块,它承担着让读者理解站点信息架构、快速定位目标页面的职责。本文基于 VitePress 默认主题,系统讲解themeConfig.sidebar的完整配置能力:从最简单的链接数组,到按路由区分的多侧边栏对象、可折叠分组,再到base路径前缀的自动化拼接,并结合仓库源码与类型定义说明其底层解析逻辑。读完本文,你将能独立为任意文档站设计出结构清晰、可折叠、可多区域切换的侧边栏。
侧边栏配置入口:themeConfig.sidebar
侧边栏菜单在主题配置的themeConfig.sidebar字段中定义,完整配置可参考 默认主题配置文档。其最基础的形式是传入一个链接数组:
export default { themeConfig: { sidebar: [ { text: 'Руководство', items: [ { text: 'Введение', link: '/ru/introduction' }, { text: 'Первые шаги', link: '/ru/getting-started' }, ... ] } ] } }从类型定义看(见 types/default-theme.d.ts),Sidebar类型为SidebarItem[] | SidebarMulti:数组形式用于单一侧边栏,对象形式(SidebarMulti)用于按路径区分的多侧边栏;每个SidebarItem可选字段包括text、link、items、collapsed、base,以及docFooterText、rel、target等链接辅助属性。
基础用法:数组形式的侧边栏结构
最简单的侧边栏形式是直接传入一个链接数组。第一层元素定义侧边栏的「分区(section)」,它必须包含text(分区标题)和items(实际的导航链接):
export default { themeConfig: { sidebar: [ { text: 'Заголовок секции A', items: [ { text: 'Пункт A', link: '/item-a' }, { text: 'Пункт B', link: '/item-b' }, ... ] }, { text: 'Заголовок секции B', items: [ { text: 'Пункт C', link: '/item-c' }, { text: 'Пункт D', link: '/item-d' }, ... ] } ] } }链接路径的书写规则
每个link都必须指向以/开头的实际文件路径。如果链接以斜杠结尾,VitePress 会解析为该目录下的index.md:
export default { themeConfig: { sidebar: [ { text: 'Руководство', items: [ // Ссылка на страницу `/ru/guide/index.md` { text: 'Введение', link: '/ru/guide/' } ] } ] } }嵌套层级上限:6 层
侧边栏项支持从根级开始向下嵌套最多 6 层。超过 6 层的嵌套项会被忽略,不会显示在侧边栏上:
export default { themeConfig: { sidebar: [ { text: 'Уровень 1', items: [ { text: 'Уровень 2', items: [ { text: 'Уровень 3', items: [ ... ] } ] } ] } ] } }从源码角度看,这一限制由 VPSidebarItem.vue 中的渲染条件v-if="depth < 5"实现:递归组件每深入一层depth加一,当depth达到 5(即渲染到第 6 层)时便不再继续递归,与文档描述的「6 层上限」完全对应。同时该组件还根据层级动态选择标题标签(h${props.depth + 2}),保证第 0 层分区使用h2、更深层使用h3及以下,为文档站提供语义化的标题结构。
多侧边栏(Multiple Sidebars):按路由切换
当文档包含多个相互独立的内容区块(例如「指南」与「配置」)时,可以为不同路径配置不同的侧边栏。
首先,将页面按区块组织到各自的目录中:
. ├─ guide/ │ ├─ index.md │ ├─ one.md │ └─ two.md └─ config/ ├─ index.md ├─ three.md └─ four.md然后,将sidebar从数组改为对象,以路径前缀作为键,为每个目录定义专属侧边栏:
export default { themeConfig: { sidebar: { // Эта боковая панель отображается, когда пользователь находится в директории `guide` '/guide/': [ { text: 'Руководство', items: [ { text: 'Index', link: '/guide/' }, { text: 'One', link: '/guide/one' }, { text: 'Two', link: '/guide/two' } ] } ], // Эта боковая панель отображается, когда пользователь находится в директории `config` '/config/': [ { text: 'Настройка', items: [ { text: 'Index', link: '/config/' }, { text: 'Three', link: '/config/three' }, { text: 'Four', link: '/config/four' } ] } ] } } }匹配规则与源码实现
多侧边栏的匹配逻辑在 support/sidebar.ts 的getSidebar函数中实现。其核心算法是:将配置对象的所有键按路径段数降序排序(b.split('/').length - a.split('/').length),然后找出第一个与当前路径匹配的键,从而保证「/multi-sidebar/nested/这样的深层路径优先于/multi-sidebar/与/」被命中。该函数对guide/与/guide/两种写法都做了归一化处理(ensureStartingSlash)。
对应测试见tests/unit/client/theme-default/support/sidebar.test.ts,分别覆盖了键顺序正常、键顺序反转以及嵌套键三种场景,验证了「未命中任何键时回退到/侧边栏」的行为。若没有任何键匹配,getSidebar返回空数组,此时侧边栏不显示。
可折叠分组(Collapsible Sidebar Groups)
在侧边栏分组上添加collapsed选项,即可为每个分区显示展开/收起切换按钮:
export default { themeConfig: { sidebar: [ { text: 'Заголовок секции A', collapsed: false, items: [...] } ] } }所有分区默认是「展开」状态。如果希望页面初次加载时分区「收起」,将collapsed设为true:
export default { themeConfig: { sidebar: [ { text: 'Заголовок секции A', collapsed: true, items: [...] } ] } }折叠交互的源码细节
折叠行为由 composables/sidebar.ts 的useSidebarItemControl组合式函数驱动:
collapsible判定依据是item.value.collapsed != null——即只有显式指定了collapsed的分组才会出现折叠按钮,未指定时分组不可折叠;- 展开/收起状态通过
watchEffect与item.value.collapsed保持同步(collapsed.value = !!(collapsible.value && item.value.collapsed)); - 当分组内任一链接处于激活状态时(
hasActiveLink),分组会自动展开(nextTick(() => (collapsed.value = false))),确保用户通过 URL 直达或切换页面时能看到当前所在的分组内容,避免「激活链接被折叠隐藏」的困惑; - 激活状态判断依赖 support/sidebar.ts 中的
hasActiveLink,它会递归遍历嵌套items检测是否存在匹配当前路径的链接。
在模板层面(VPSidebarItem.vue),折叠按钮仅在「显式设置collapsed且存在子项」时渲染,并通过aria-expanded暴露折叠状态、通过aria-label="toggle section"提供无障碍语义。分区样式上,level-0激活链接左侧会有主题色指示条(var(--vp-c-brand-1)),帮助用户定位当前位置。
路径前缀base:消除重复路径
当文档结构包含深层目录、或多个分组同处于一个子目录时,可以使用base选项为组内所有嵌套items自动拼接路径前缀,从而避免为每个link重复书写相同的路径。
base在多侧边栏配置与嵌套侧边栏分组中均受支持。
在多侧边栏中使用base
可以在某个侧边栏分区的配置根部定义base:
export default { themeConfig: { sidebar: { '/guide/': { base: '/guide/', items: [ // Эта ссылка будет разрешена в `/guide/introduction` { text: 'Введение', link: 'introduction' }, // Эта ссылка будет разрешена в `/guide/getting-started` { text: 'Первые шаги', link: 'getting-started' } ] } } } }在嵌套分组中使用base
base同样可用于嵌套分组,此时它作用于该分组的直接子项。嵌套的base会覆盖父分组的路径前缀:
export default { themeConfig: { sidebar: [ { text: 'Справочник', base: '/reference/', items: [ // Эта ссылка будет разрешена в `/reference/site-config` { text: 'Конфигурация сайта', link: 'site-config' }, { text: 'Тема по умолчанию', // Вложенный `base` переопределяет префикс пути родительской группы base: '/reference/default-theme-', items: [ // Эта ссылка будет разрешена в `/reference/default-theme-nav` { text: 'Навигация', link: 'nav' }, // Эта ссылка будет разрешена в `/reference/default-theme-sidebar` { text: 'Сайдбар', link: 'sidebar' } ] } ] } ] } }base拼接的源码实现
base的解析发生在 support/sidebar.ts 的addBase函数中。它递归遍历侧边栏项,遵循以下规则:
- 每个项优先使用自身的
base,否则继承父级传入的_base; - 只有当项存在
link且不是外部链接(!isExternal(item.link))时才拼接前缀——外部链接(如https://...)会被原样保留; - 拼接时处理斜杠边界:如果链接以
/开头而base以/结尾,则去掉链接开头的斜杠以避免双斜杠;若base不以/结尾则补上/; - 拼接后的前缀会继续沿
items向下传递(addBase(item.items, base)),实现整棵子树的前缀继承。
这一行为有对应的单元测试验证(见 sidebar.test.ts):测试「applies base only to internal links」确认了base仅作用于站内链接——相对链接intro被解析为/en/intro,以/开头的root被解析为/en/root,而https://example.com/这类外部链接不受base影响。
侧边栏与页面的联动:激活态与分组聚合
除了配置本身,理解侧边栏如何「感知」当前页面有助于排查问题。getSidebar之后,主题还会通过 getSidebarGroups 将「无items的平铺链接」自动聚合进前一个分组,保证渲染结构的统一;而 getFlatSideBarLinks 则会递归展平所有嵌套链接并保留docFooterText、rel、target元数据,这些数据被「上一页/下一页」导航与搜索等功能复用。
在 SSR 与客户端水合阶段,useSidebarItemControl会在 setup 期间执行一次updateActiveLink(true)(跳过 hash 检查)以保证服务端渲染的输出中也带有正确的激活样式,并在路由变化、组件挂载后重新计算精确的激活链接(composables/sidebar.ts)。侧边栏整体的显隐则由hasSidebar与sidebarGroups驱动(见 VPSidebar.vue),在窄屏下作为抽屉式导航呈现、宽屏下常驻页面左侧。
小结
本文完整覆盖了 VitePress 默认主题侧边栏的四种核心配置能力:数组形式的单一侧边栏(含 6 层嵌套上限与/结尾解析index.md的规则)、对象形式的多侧边栏(按路径前缀切换并支持深层键优先匹配)、collapsed可折叠分组(默认展开、可设置初始收起、激活时自动展开),以及base路径前缀(支持多侧边栏根部与嵌套分组内定义、可覆盖继承、对外部链接豁免)。结合 types/default-theme.d.ts 的类型定义、support/sidebar.ts 的解析逻辑与 单元测试 的验证用例,你可以放心地依据这些规则搭建出适配任意文档架构的导航体系。
【免费下载链接】vitepressVite & Vue powered static site generator.项目地址: https://gitcode.com/gh_mirrors/vi/vitepress
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考