Slidev 项目目录结构完全指南:以约定驱动组件、布局、样式与全局图层的扩展机制

发布时间:2026/9/8 23:43:35

Slidev 项目目录结构完全指南:以约定驱动组件、布局、样式与全局图层的扩展机制
Slidev 项目目录结构完全指南以约定驱动组件、布局、样式与全局图层的扩展机制【免费下载链接】slidevPresentation Slides for Developers项目地址: https://gitcode.com/GitHub_Trending/sl/slidevSlidevPresentation Slides for Developers采用一套「约定优于配置」的目录结构约定用固定的文件与文件夹位置替代繁琐的配置项让开发者在几乎零配置的情况下即可扩展组件、布局、全局样式与页面图层。本文以官方文档 directory-structure.md 为骨架结合仓库源码packages/slidev/node与packages/client逐一剖析这些约定的加载机制与优先级帮助你正确组织自己的演示项目并能复现、验证每一步行为。目录约定总览在任意 Slidev 项目中默认约定的一级目录/文件结构如下your-slidev/ ├── components/ # 自定义组件 ├── layouts/ # 自定义布局 ├── public/ # 静态资源 ├── setup/ # 自定义 setup / hooks ├── snippets/ # 代码片段 ├── styles/ # 自定义样式 ├── index.html # 向最终 index.html 注入内容 ├── slides.md # 幻灯片主入口 └── vite.config.ts # 扩展 vite 配置以上所有目录与文件都是可选的全部缺席时 Slidev 也能直接运行纯 Markdown 幻灯片。其中slides.md是默认的演示入口vite.config.ts用于以 Vite 配置 的方式扩展构建链其余目录则分别对应本文接下来详解的扩展点。值得注意的一点是这些约定并非只对「用户项目根目录」生效。从 options.ts 的解析逻辑可以看到Slidev 会把主题目录themeRoots、插件目录addonRoots与用户目录userRoot合并为一组roots见 options.ts随后所有约定目录components、layouts、styles、setup、index.html等都会在每一个 root 中逐一查找并最终合并。这意味着主题与插件遵循同一套目录规范而你的项目目录拥有最高优先级的覆盖能力。自定义组件components/匹配规则./components/*.{vue,js,ts,jsx,tsx,md}放置在components/下的文件会作为全局可用组件无需手动 import直接在slides.md中书写即可# My Slide MyComponent :count4/组件来源共有三个层次见 组件使用指南Slidev 内置组件详见 内置组件对应源码位于 packages/client/builtin由主题与插件addons提供你项目components/目录下的自定义组件。其自动导入由unplugin-vue-components驱动源码位于 components.ts。关键实现如下见 components.tsComponents({ extensions: [vue, md, js, ts, jsx, tsx], dirs: [ join(clientRoot, builtin), ...roots.map(i join(i, components)), ], ... })几点与「目录约定」直接相关的结论dirs数组把内置组件目录clientRoot/builtin与每一个 root 下的components全部纳入扫描因此主题、插件、用户三方组件可以同名共存并合并支持.vue、.md、.js、.ts、.jsx、.tsx六种文件形态.md组件即 Markdown 写成的小型幻灯片片段由于用户 root 排在dirs末尾自定义组件在解析中处于相对靠后的位置这也是「用户目录拥有最终覆盖权」约定的一部分。如果你希望把组件打包成可复用的插件分享给他人可以参考 主题与插件Addon指南 与 编写 Addon。自定义布局layouts/匹配规则./layouts/*.{vue,js,ts,jsx,tsx}布局是包裹每一页幻灯片内容的 Vue 组件通过在幻灯片 frontmatter 中声明layout字段来使用见 布局指南--- layout: quote --- A quote from someone默认约定第一页使用cover布局其余页面使用default布局。内置布局列表见 内置布局源码位于 packages/client/layouts包含default.vue、cover.vue、two-cols.vue、section.vue、center.vue、quote.vue等。布局目录的扫描逻辑在 options.ts 的getLayouts中实现值得注意的实现细节扫描的 glob 是layouts/**/*.{vue,js,mjs,ts,mts}即支持子目录嵌套布局名取自basename去扩展名最终以「后写入者覆盖」的方式填入layouts映射扫描顺序为内置布局目录clientRoot→ 主题 → 插件 → 用户 root因此内置布局 → 主题布局 → 插件布局 → 自定义布局用户后加载者覆盖先加载者见 布局指南 与 options.ts。换句话说只要在项目layouts/下创建与内置布局同名的.vue文件即可整体替换该内置布局想从零编写布局可参考 编写布局。静态资源public/匹配规则./public/*该目录的语义与 Vite 的publicDir完全一致开发阶段目录内容以根路径/提供服务例如public/logo.png可用/logo.png访问构建阶段目录内容被原样拷贝到dist的根目录。源码中的对应实现位于 extendConfig.tspublicDir: join(options.userRoot, public),而主题与插件携带的public/目录则由 staticCopy.ts 使用vite-plugin-static-copy一并拷贝到构建产物实现「主题自带 logo/素材随构建输出」的能力。在实际演讲内容中你可以直接在 Markdown 或组件的src/href里使用根路径引用这些资源例如![](/logo.png)。关于 base path、远程图片等更细致的资源处理策略参见 资源处理 FAQ。自定义样式style.css/styles/匹配规则./style.css或./styles/index.{css,js,ts}命中约定的样式入口会被注入到应用根节点App root。若需要拆分多个 CSS 文件推荐使用styles/目录并在index.ts中手动管理导入顺序your-slidev/ ├── ... └── styles/ ├── index.ts ├── base.css ├── code.css └── layouts.css// styles/index.ts import ./base.css import ./code.css import ./layouts.css从源码看加载逻辑位于虚拟模块 conditional-styles.ts它对每个 root 依次尝试styles/index.{ts,js,css}、styles.{ts,js,css}、style.{ts,js,css}三种形态并全部导入见 conditional-styles.ts因此上表中的三种写法根级style.css、根级styles.css、目录化styles/index.*都是合法的入口。官方约定只枚举了style.css与styles/index.*其余两套是兼容性保障。样式会依次经过UnoCSS与PostCSS处理因此开箱即用地支持CSS 嵌套Nested CSSUnoCSS 指令transformer-directives如apply与--uno:快捷写法theme()函数读取 UnoCSS 主题色。一个典型的主题化全局样式示例官方文档示例.slidev-layout { --uno: px-14 py-10 text-[1.1rem]; h1, h2, h3, h4, p, div { --uno: select-none; } pre, code { --uno: select-text; } a { color: theme(colors.primary); } }::: warning 此处注入的全局 CSS同样会作用于演示者presenter界面。为了避免样式泄漏到演示者模式请尽量把样式作用域收窄到单张幻灯片或将选择器包裹在.slidev-layout之下。 :::示例请使用.slidev-layout .grid { ... }而不要直接写.grid { ... }。「尽量作用域化」的另一条正路是把样式放进幻灯片自身的style标签或使用style作用域机制相关讲解见 幻灯片作用域样式 与 区块样式block frontmatter。自定义index.html注入匹配规则项目根目录下的index.html该文件用于向 Slidev 最终生成的宿主 HTML 注入额外的head标签如外部字体、meta与body脚本。例如自定义文件见 directory-structure.mdhead link relpreconnect hrefhttps://fonts.gstatic.com link hrefhttps://fonts.googleapis.com/css2?familyFiraCode:wght400;600familyNunitoSans:wght200;400;600displayswap relstylesheet /head body script src./your-scripts/script /body合并后的最终宿主页面形如!DOCTYPE html html langen head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 link relicon typeimage/png hrefhttps://cdn.jsdelivr.net/gh/slidevjs/slidev/assets/favicon.png !-- injected head -- link relpreconnect hrefhttps://fonts.gstatic.com link hrefhttps://fonts.googleapis.com/css2?familyFiraCode:wght400;600familyNunitoSans:wght200;400;600displayswap relstylesheet /head body div idapp/div script typemodule src__ENTRY__/script !-- injected body -- script src./your-scripts/script /body /html底层实现在 indexHtml.tsSlidev 会遍历所有 root 读取各自的index.html用parseHtmlForUnheadExtraction解析head中的标签并合并进最终的 head 输出见 indexHtml.ts同时把body中的内容抽取出来追加到宿主模板的!-- body --标记处见 indexHtml.ts。由此可以总结出两条重要规则只写片段不要写完整文档若用户index.html包含!DOCTYPE声明Slidev 会直接忽略该文件并输出警告——这个文件很可能是被误放进项目的生成物见 indexHtml.tsSlidev 自身会生成title、favicon、description、Open Graph、Twitter Card、字体link等相关细节见 SEO Meta所以index.html只应补充它没有覆盖的第三方标签与脚本。全局图层文件匹配规则global-top.vue|global-bottom.vue|custom-nav-controls.vue|slide-top.vue|slide-bottom.vue这些文件用于创建跨幻灯片持续存在的图层适合页脚、全局特效、跨页动画等场景。完整用法与示例见 全局图层Global Layers其图层在 Z 轴上从顶层到底层依次为NavControls含自定义导航控件custom-nav-controls.vueGlobal Topglobal-top.vue单实例Slide Topslide-top.vue每张幻灯片一个实例Slide Content幻灯片正文Slide Bottomslide-bottom.vue每张幻灯片一个实例Global Bottomglobal-bottom.vue单实例例如在项目根目录创建global-bottom.vue!-- global-bottom.vue -- template footer classabsolute bottom-0 left-0 right-0 p-2Your Name/footer /template这段文字会出现在所有幻灯片上。结合 全局上下文$nav 还可以做条件渲染例如「隐藏第 4 页 / cover 布局的页脚」!-- 从第 4 页起隐藏页脚 -- template footer v-if$nav.currentPage ! 4 classabsolute bottom-0 left-0 right-0 p-2 Your Name /footer /template!-- 在 cover 布局中隐藏页脚 -- template footer v-if$nav.currentLayout ! cover classabsolute bottom-0 left-0 right-0 p-2 Your Name /footer /template注意若global-top.vue/global-bottom.vue依赖当前导航状态导出 PDF 时应使用--per-slide参数以确保每页状态正确或者直接改用按页生效的slide-top.vue/slide-bottom.vue。从源码 global-layers.ts 可以看到加载器会为每个 root 生成*.{ts,js,vue}的导入 glob并额外兼容一组候选命名见 global-layers.tsglobal-top/GlobalTop、global-bottom/GlobalBottom、slide-top/SlideTop、slide-bottom/SlideBottom。也就是说这些图层文件对大小写与连字符命名都是宽容的。此外模板为全局/单页图层生成了GlobalTop/GlobalBottom组件顶层为h(comp)渲染而custom-nav-controls走独立的导航控件虚拟模块二者机制相互独立。容易被忽略的两个约定目录setup/与snippets/目录树中的另外两个成员虽然没有专属小节但它们同样是目录约定的组成部分。setup/自定义 setup / hooks匹配规则./setup/hook-name.{ts,js}。Slidev 在启动时会为每个 root 解析setup/filename并把模块的default导出当作 hook 函数调用见 load.tsexport async function loadSetupsF(roots, filename, args) { return await Promise.all(roots.flatMap((root) { const path resolve(root, setup, filename) if (existsSync(path)) { tasks.push(loadModule{ default: F }(path).then(mod mod.default(...args))) } ... })) }例如仓库自身对主题/高亮、KaTeX、预解析器、Shiki transformer 等的接入就位于 node/setups。你可以通过创建setup/shiki.ts、setup/katex.ts、setup/code-runners.ts、setup/preparser.ts等文件覆盖/扩展对应能力——每类 hook 的完整配置与示例在 docs/custom 目录下有对应专题如 config-highlighter.md、config-katex.md、config-code-runners.md、config-parser.md 等查阅 目录索引 可快速定位全部可用 hook。snippets/代码片段匹配规则./snippets/*。这里的文件会被 Shiki 的代码块导入语法按需读取例如在代码块内使用 /snippets/foo.ts/指向项目根把外部文件内容拉进幻灯片并做语法高亮可配合#region选取指定片段或使用行号范围 /snippets/external.ts#snippet ts /snippets/snippet.ts#snippet ts这种写法在仓库的 magic-move 集成测试中直接可见见 magic-move.test.ts说明片段导入在语法转换管线中是先于代码块解析执行的且修改片段源文件会触发对应幻灯片的增量更新。完整语法请参考 代码片段导入。参考一个最小真实项目形态仓库的 demo/starter 就是这套约定的最小实现包含components/Counter.vue、pages/imported-slides.md分页导入、snippets/external.ts、根级style.css与vite.config.ts目录里甚至没有layouts/、setup/、public/与index.html——再次印证了「所有约定项均可选、按需声明」的设计取向。当你开始自己的演讲项目时建议同样遵循「先放slides.md跑通再按需增量加入上述目录」的路径某一天你想放个全局页脚就新建global-bottom.vue想让代码引用外部文件就新建snippets/想统一风格就新建styles/——每一处都是位置即语义不需要任何额外配置。【免费下载链接】slidevPresentation Slides for Developers项目地址: https://gitcode.com/GitHub_Trending/sl/slidev创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

STM32水位监测系统:ADC采样、I2C驱动OLED与传感器标定实战

STM32水位监测系统:ADC采样、I2C驱动OLED与传感器标定实战

2026/9/8 23:43:35

1. 项目概述:为什么一个水位监测系统值得花三天时间从头搭起我第一次在鱼缸边调试这个STM32水位监测系统时,手边只有一块STM32F103C8T6最小系统板、一块I2C接口的0.96寸OLED屏和一个淘宝上十块钱包邮的WaterSensor水位传感器。没有现成的库,没…

Angular 测试迁移实操:用 RouterTestingModule migration 将测试平滑迁移到 RouterModule

Angular 测试迁移实操:用 RouterTestingModule migration 将测试平滑迁移到 RouterModule

2026/9/8 23:43:35

Angular 测试迁移实操:用 RouterTestingModule migration 将测试平滑迁移到 RouterModule 【免费下载链接】angular Deliver web apps with confidence 🚀 项目地址: https://gitcode.com/GitHub_Trending/an/angular Angular 官方在 RouterTesti…

res-downloader:简单上手的网络资源捕获下载工具

res-downloader:简单上手的网络资源捕获下载工具

2026/9/8 23:43:35

res-downloader:简单上手的网络资源捕获下载工具 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-downloader 它帮你把网页、视…

Android Studio学生信息管理系统源码解析:从环境搭建到功能实现

Android Studio学生信息管理系统源码解析:从环境搭建到功能实现

2026/9/9 0:33:38

简介:这套基于Android Studio开发的学生信息管理系统源码,是作者大四毕业设计的高分项目(评审分98.5分),主要面向计算机相关专业准备毕业设计、课程设计或期末大作业的学生,也适合需要Android项目实战练习的…

VSCode Claude Code插件配置指南:从安装到中转API避坑全解析

VSCode Claude Code插件配置指南:从安装到中转API避坑全解析

2026/9/9 0:33:38

先说个实际场景:你在VSCode里装好Claude Code插件,满心期待让它帮你改代码、写测试、梳理项目结构,结果点开面板要么报401认证失败,要么提示model not found,要么直接转圈半天最后超时。这几乎是每个刚接触Claude Code…

Claude Code完整实战指南:安装配置、MCP与Skills应用全解析

Claude Code完整实战指南:安装配置、MCP与Skills应用全解析

2026/9/9 0:33:37

老早就想把Claude Code的完整用法写下来,这阵子项目里的文件整理、脚本调试、代码重构,几乎都是开着终端用Claude Code在处理。它的思路和传统的AI聊天窗口完全不同,不是一问一答就结束,而是给你一个正在干活的人:你交…

opencode实战:终端AI编程助手安装配置与进阶玩法

opencode实战:终端AI编程助手安装配置与进阶玩法

2026/9/9 0:33:37

我前段时间被一个项目折腾得不轻:团队散落在三个时区,代码仓库老得没人敢重构,新来的同事光看项目文档就要看两天。后来朋友甩给我一个终端工具 opencode,说我试试用它"接手旧项目"。我本来没抱希望,结果它一…

MATLAB仿真2ASK、2FSK、2PSK调制解调原理与代码详解

MATLAB仿真2ASK、2FSK、2PSK调制解调原理与代码详解

2026/9/9 0:33:37

简介:二进制幅度键控(2ASK)、频移键控(2FSK)和相移键控(2PSK)是数字通信中最基础的三种调制方式,也是通信原理课程的核心仿真内容。这份MATLAB项目面向通信工程、电子信息类本科生及…

沙迪克操作面板详解:从按键布局到坐标设定与菜单逻辑

沙迪克操作面板详解:从按键布局到坐标设定与菜单逻辑

2026/9/9 0:23:37

简介:这份资源是SODICK(沙迪克)数控电火花机床操作面板模拟软件的RAR压缩包,面向模具制造及精密加工领域的学习者、培训学员和编程人员,用于在普通PC上体验与实体机床一致的控制界面与操作流程。压缩包共2000个文件&am…

中国人民大学杨琳团队《Nature Communications》 | 全球潮汐湿地土壤有机碳时空格局与环境驱动:一项2009-2020年的全球评估

中国人民大学杨琳团队《Nature Communications》 | 全球潮汐湿地土壤有机碳时空格局与环境驱动:一项2009-2020年的全球评估

2026/9/7 20:21:46

本文首发于“生态学者”!从“湿地面积”到“土壤碳密度”:为什么需要重新认识潮汐湿地蓝碳变化?潮汐湿地位于陆地与海洋的交汇地带,包括红树林、盐沼和潮滩,是全球重要的蓝碳生态系统。其土壤能够长期储存大量有机碳&a…

adb抓包

adb抓包

2026/9/8 4:55:53

前言 本文介绍如何通过 tcpdump 在 Android 手机上抓取网络数据包,并在电脑端使用 Wireshark 进行分析。适用于需要排查 App 网络请求、分析接口调用或调试网络问题的开发与测试场景。1. 手机要有 root 权限2. 下载 tcpdump3. adb push C:\Users\zhangkuixun\Downlo…

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战

2026/9/8 22:37:26

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战 在云原生基础设施中,容器镜像体积直接决定了服务的部署速度与弹性扩容敏捷度。对于传统的 Go / Java 微服务,镜像体积通常被严格控制在 50MB 到 200MB 以内,拉取镜像只…

扩散模型图像恢复实战:从DDPM原理到PyQt5可视化系统

扩散模型图像恢复实战:从DDPM原理到PyQt5可视化系统

2026/9/9 0:03:36

简介:面向毕业设计场景的PyQt5扩散模型图像恢复项目,提供完整Python源码与项目说明,适合图像处理、深度学习方向的高年级本科生与研究生参考。项目在模块设计上覆盖图像处理、扩散模型、参数配置、用户界面与结果评估五部分,具体涉…

开关电源环路裕量测试实战:相位裕量与增益裕量详解

开关电源环路裕量测试实战:相位裕量与增益裕量详解

2026/9/9 0:03:36

1. 项目概述:为什么环路裕量测试是电子工程师绕不开的“体检项目”“从零开始的电子工程师生活(6)——环路裕量测试”,这个标题一出来,老电源工程师可能已经下意识摸了摸示波器探头,新同事则大概率在想&…

定时插座芯片怎么选?专用定时IC与单片机MCU选型对比

定时插座芯片怎么选?专用定时IC与单片机MCU选型对比

2026/9/9 0:03:36

拆开市面上不同价位的定时插座,你会发现一个有意思的现象:有的里面躺着一颗黑色的软封装芯片,丝印都看不清;有的则是一块小小的蓝色或绿色PCB,上面赫然印着STM8或者STC的字样。同样叫"定时插座",…

远程协作的工作台整理

远程协作的工作台整理

2026/9/8 4:23:39

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/8 3:19:39

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/8 4:00:23

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…