├── .npmrc ├── .gitignore ├── public ├── logo.png ├── favicon.png ├── og-image.png ├── demo-cover.png ├── logo-circle.png ├── logo-square.png ├── logo-title.png ├── logo-triangle.png ├── logo-for-vscode.png ├── screenshots │ ├── cover.png │ ├── covers.png │ ├── navbar.png │ ├── recording.png │ ├── presenter-mode.png │ ├── slides-overview.png │ └── integrated-editor.png ├── theme-placeholder.png ├── showcases │ └── composable-vue.png ├── assets │ └── arrow-bottom-left.svg └── logo.svg ├── index.md ├── eslint.config.js ├── .vitepress ├── theme │ ├── composables │ │ └── dark.ts │ ├── components │ │ ├── FeaturesAnimation.vue │ │ ├── SeeAlso.vue │ │ ├── ShowCases.vue │ │ ├── AddonGallery.vue │ │ ├── ThemeGallery.vue │ │ ├── DemoSlide.vue │ │ ├── Environment.vue │ │ ├── DemoEditor.vue │ │ ├── LandingPage.vue │ │ ├── SlideContainer.vue │ │ ├── FeaturesOverview.vue │ │ ├── LinkInline.vue │ │ ├── FeaturesAnimationInner.vue │ │ ├── AddonInfo.vue │ │ ├── LinkCard.vue │ │ ├── TheTweet.vue │ │ ├── Layout.vue │ │ ├── ShowCaseInfo.vue │ │ ├── FeatureTag.vue │ │ ├── ThemeInfo.vue │ │ └── Demo.vue │ ├── index.ts │ └── styles │ │ ├── custom.css │ │ ├── demo.css │ │ └── vars.css ├── addons.ts ├── customizations.ts ├── utils.ts ├── pages.ts ├── sidebar-gen.ts └── config.ts ├── .github ├── pull_request_template.md └── workflows │ └── autosync.yml ├── resources ├── showcases.md ├── covers.md ├── addon-gallery.md ├── theme-gallery.md └── learning.md ├── features ├── side-editor.md ├── eject-theme.md ├── click-marker.md ├── monaco-write.md ├── transform-component.md ├── zoom-slide.md ├── canvas-size.md ├── code-block-max-height.md ├── plantuml.md ├── slide-hook.md ├── block-frontmatter.md ├── code-block-line-numbers.md ├── twoslash.md ├── bundle-remote-assets.md ├── build-with-pdf.md ├── mdc.md ├── frontmatter-merging.md ├── mermaid.md ├── recording.md ├── slide-scope-style.md ├── direction-variant.md ├── monaco-editor.md ├── import-snippet.md ├── monaco-run.md ├── importing-slides.md ├── rough-marker.md ├── prettier-plugin.md ├── line-highlighting.md ├── slot-sugar.md ├── drawing.md ├── remote-access.md ├── shiki-magic-move.md ├── draggable.md ├── latex.md ├── icons.md ├── index.data.ts ├── global-layers.md ├── vscode-extension.md └── index.md ├── custom ├── config-katex.md ├── config-routes.md ├── config-vue.md ├── config-shortcuts.md ├── config-context-menu.md ├── config-mermaid.md ├── config-transformers.md ├── config-unocss.md ├── config-vite.md ├── config-highlighter.md ├── config-code-runners.md ├── config-fonts.md ├── config-monaco.md ├── directory-structure.md ├── config-parser.md └── index.md ├── guide ├── layout.md ├── component.md ├── write-layout.md ├── write-addon.md ├── theme-addon.md ├── write-theme.md ├── faq.md ├── global-context.md ├── why.md ├── syntax.md ├── exporting.md ├── ui.md ├── index.md └── hosting.md ├── uno.config.ts ├── tsconfig.json ├── netlify.toml ├── vite.config.ts ├── package.json ├── .vscode └── settings.json ├── builtin ├── cli.md └── layouts.md ├── README.md └── components.d.ts /.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | strict-peer-dependencies=false 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .vitepress/@slidev 4 | .vitepress/cache 5 | -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/logo.png -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/favicon.png -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | markdownStyles: false 4 | --- 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/og-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/og-image.png -------------------------------------------------------------------------------- /public/demo-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/demo-cover.png -------------------------------------------------------------------------------- /public/logo-circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/logo-circle.png -------------------------------------------------------------------------------- /public/logo-square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/logo-square.png -------------------------------------------------------------------------------- /public/logo-title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/logo-title.png -------------------------------------------------------------------------------- /public/logo-triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/logo-triangle.png -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import antfu from '@antfu/eslint-config' 2 | 3 | export default antfu({ 4 | 5 | }) 6 | -------------------------------------------------------------------------------- /public/logo-for-vscode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/logo-for-vscode.png -------------------------------------------------------------------------------- /public/screenshots/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/screenshots/cover.png -------------------------------------------------------------------------------- /public/theme-placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/theme-placeholder.png -------------------------------------------------------------------------------- /public/screenshots/covers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/screenshots/covers.png -------------------------------------------------------------------------------- /public/screenshots/navbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/screenshots/navbar.png -------------------------------------------------------------------------------- /public/screenshots/recording.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/screenshots/recording.png -------------------------------------------------------------------------------- /.vitepress/theme/composables/dark.ts: -------------------------------------------------------------------------------- 1 | import { useDark } from '@vueuse/core' 2 | 3 | export const isDark = useDark() 4 | -------------------------------------------------------------------------------- /public/showcases/composable-vue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/showcases/composable-vue.png -------------------------------------------------------------------------------- /public/screenshots/presenter-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/screenshots/presenter-mode.png -------------------------------------------------------------------------------- /public/screenshots/slides-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/screenshots/slides-overview.png -------------------------------------------------------------------------------- /public/screenshots/integrated-editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slidevjs/docs-cn/HEAD/public/screenshots/integrated-editor.png -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | - [ ] 我对翻译内容的改动不包含基于英文原版的扩展、删减或演绎 (如有,请移步至[主仓库](https://github.com/slidevjs/slidev)) 2 | 3 | **问题描述**: 4 | -------------------------------------------------------------------------------- /resources/showcases.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | --- 4 | 5 | # 案例展示 6 | 7 | 使用 Slidev 制作的演示文档/演讲。 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.vitepress/theme/components/FeaturesAnimation.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 14 | -------------------------------------------------------------------------------- /.vitepress/theme/components/SeeAlso.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | -------------------------------------------------------------------------------- /.vitepress/theme/components/ShowCases.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /features/side-editor.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/ui#navigation-actions 4 | relates: 5 | - features/vscode-extension 6 | tags: [编辑器] 7 | description: | 8 | 在放映模式下编辑你的幻灯片源文件。 9 | --- 10 | 11 | # 内嵌编辑器 12 | 13 | Slidev 附带了一个集成编辑器,可以立即重载并保存对文件的更改。 14 | 15 | 点击导航栏中的 来打开它。 16 | 17 | ![](/screenshots/integrated-editor.png) 18 | -------------------------------------------------------------------------------- /custom/config-katex.md: -------------------------------------------------------------------------------- 1 | # 配置 KaTeX 2 | 3 | 4 | 5 | 创建一份包含以下内容的 `./setup/katex.ts` 文件: 6 | 7 | ```ts twoslash 8 | import { defineKatexSetup } from '@slidev/types' 9 | 10 | export default defineKatexSetup(() => { 11 | return { 12 | maxExpand: 2000, 13 | /* ... */ 14 | } 15 | }) 16 | ``` 17 | 18 | 返回值应当是 KaTeX 的自定义选项。 19 | 20 | 请参阅 [KaTeX的文档](https://katex.org/docs/options.html) 或选项列表的类型定义。 21 | -------------------------------------------------------------------------------- /resources/covers.md: -------------------------------------------------------------------------------- 1 | # 精选封面 {#curated-covers} 2 | 3 | 我们精心挑选了一些封面图片,用以展示在我们的初始模板中。 4 | 5 | ![](/screenshots/covers.png) 6 | 7 | ```yaml 8 | --- 9 | # 来自精选集的随机图片 10 | background: https://cover.sli.dev 11 | --- 12 | ``` 13 | 14 | 如果你喜欢这些图片,可以访问我们的 [Unsplash 合集](https://unsplash.com/collections/94734566/slidev),同时还能了解它们的作者。 15 | 16 | 目前,[cover.sli.dev](https://cover.sli.dev) 的内容来自于 [`slidevjs/slidev-covers` 仓库](https://github.com/slidevjs/slidev-covers)。 17 | -------------------------------------------------------------------------------- /features/eject-theme.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/theme-addon 4 | tags: [主题, CLI] 5 | description: | 6 | 项目中弹出已安装的主题以进行自定义。 7 | --- 8 | 9 | # 弹出主题 10 | 11 | 如果你想对当前的主题拥有完全的掌控,你可以将它 **弹出**(eject)到本地的文件系统,并且随心所欲地修改它。可以使用以下命令: 12 | 13 | ```bash 14 | $ slidev theme eject 15 | ``` 16 | 17 | 这会将你当前使用的主题弹出到 `./theme` 目录下,然后自动将你的 frontmatter 修改为: 18 | 19 | ```yaml 20 | --- 21 | theme: ./theme 22 | --- 23 | ``` 24 | 25 | 如果你想在现有的主题上制作主题,这样会很方便。当然如果你这么做了,记得标明原主题和作者哦 :) 26 | 27 | 关于命令 `theme` 的更多选项,请参考 [Theme 命令](../builtin/cli#theme) 部分 -------------------------------------------------------------------------------- /.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | import Theme from 'vitepress/theme' 2 | import type { EnhanceAppContext } from 'vitepress' 3 | import TwoSlash from '@shikijs/vitepress-twoslash/client' 4 | import Layout from './components/Layout.vue' 5 | 6 | import '@shikijs/vitepress-twoslash/style.css' 7 | import './styles/vars.css' 8 | import './styles/demo.css' 9 | import './styles/custom.css' 10 | import 'uno.css' 11 | 12 | export default { 13 | extends: Theme, 14 | enhanceApp({ app }: EnhanceAppContext) { 15 | app.use(TwoSlash as any) 16 | }, 17 | Layout, 18 | } 19 | -------------------------------------------------------------------------------- /.vitepress/theme/components/AddonGallery.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 19 | -------------------------------------------------------------------------------- /.vitepress/theme/components/ThemeGallery.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 19 | -------------------------------------------------------------------------------- /guide/layout.md: -------------------------------------------------------------------------------- 1 | # 幻灯片布局 2 | 3 | Slidev 中的布局用于定义每张幻灯片的结构。它们是包装幻灯片内容的 Vue 组件。 4 | 5 | ## 使用布局 {#use} 6 | 7 | 要使用布局,你可以在幻灯片的 frontmatter 中指定它: 8 | 9 | ```md 10 | --- 11 | layout: quote 12 | --- 13 | 14 | A quote from someone 15 | ``` 16 | 17 | 第一张幻灯片的默认布局是 `cover`,其余的是 `default`。 18 | 19 | 布局按以下顺序加载,最后加载的会覆盖之前的: 20 | 21 | 1. 默认布局。参见 [内置布局](../builtin/layouts)。 22 | 2. 主题提供的布局 23 | 3. 插件提供的布局 24 | 4. `layouts` 目录中的自定义布局 25 | 26 | 29 | 30 | ## 编写布局 {#write} 31 | 32 | 33 | -------------------------------------------------------------------------------- /features/click-marker.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/syntax#notes 4 | - guide/animations 5 | since: v0.48.0 6 | tags: [演讲者, 动画] 7 | description: | 8 | 根据点击动画高亮演讲者笔记。 9 | --- 10 | 11 | # 笔记的动画标记 12 | 13 | 对于一些幻灯片,你可能会有较长的备注,这可能会让你难以找到特定的位置。Slidev 支持点击标记功能,它允许你从对应的内容中突出显示并自动滚动到备注的特定部分。在备注中放置 `[click]` 标记,以便在需要转到另一个 [click](/guide/animations#click-animation) 时进行定位。Slidev 会在点击标记之间的内容中进行划分,并在演示者备注中突出显示,这与你的幻灯片进度是同步的。 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /features/monaco-write.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - features/monaco-editor 4 | - features/import-snippet 5 | relates: 6 | - features/import-snippet 7 | - 自定义代码运行器: /custom/config-code-runners 8 | since: v0.49.5 9 | tags: [代码块, 编辑器] 10 | description: | 11 | 一个 monaco 编辑器,使你能够直接在幻灯片中写代码并保存到文件中。 12 | --- 13 | 14 | # 可写的 Monaco Editor 15 | 16 | 你可以使用 [引入代码片段](#import-code-snippets) 语法结合 `{monaco-write}` 指令,将 Monaco 编辑器与本地文件系统上的文件链接起来。这将允许你直接在此编辑器中编辑代码,并将更改保存回文件。 17 | 18 | ```md 19 | <<< ./some-file.ts {monaco-write} 20 | ``` 21 | 22 | 在使用此特性时,因为改动会被直接保存到文件,请确保你已经提前备份了相关文件。 23 | -------------------------------------------------------------------------------- /features/transform-component.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - guide/faq#adjust-size 4 | - features/canvas-size 5 | - features/zoom-slide 6 | tags: [布局] 7 | description: | 8 | 一个用于缩放元素的组件。 9 | --- 10 | 11 | # `Transform` 组件 12 | 13 | `Transform` 组件允许你缩放你幻灯片中的元素大小。 14 | 15 | ```md 16 | 17 | 18 | 19 | ``` 20 | 21 | 这在你想要调整部分元素的大小又不希望改变整个幻灯片布局时很有帮助。 22 | 23 | 如要缩放所有的幻灯片,你可以设置幻灯片的 canvas 大小: 24 | 25 | 26 | 27 | 如要缩放多张幻灯片,你可以考虑使用 `zoom` 选项: 28 | 29 | 30 | -------------------------------------------------------------------------------- /features/zoom-slide.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - guide/faq#adjust-size 4 | - features/canvas-size 5 | - features/transform-component 6 | tags: [布局] 7 | description: | 8 | 将幻灯片内容缩放到一个特定的比例。 9 | --- 10 | 11 | # 缩放幻灯片 12 | 13 | 你可能会发现部分幻灯片太宽敞或太拥挤。Slidev 为每张幻灯片提供了一个 `zoom` 选项来缩放幻灯片的内容: 14 | 15 | ```md 16 | --- 17 | zoom: 0.8 18 | --- 19 | 20 | # 一张有很多内容的幻灯片,该幻灯片的内容会被缩小为 80% 21 | 22 | --- 23 | 24 | # 其他幻灯片不会受到影响 25 | ``` 26 | 27 | 如要缩放所有的幻灯片,你可以设置幻灯片的 canvas 大小: 28 | 29 | 30 | 31 | 如要调整幻灯片中部分元素的大小,你可以适用 `Transform` 组件: 32 | 33 | 34 | -------------------------------------------------------------------------------- /features/canvas-size.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - guide/faq#adjust-size 4 | - features/zoom-slide 5 | - features/transform-component 6 | tags: [布局] 7 | description: | 8 | 设置所有幻灯片的大小。 9 | --- 10 | 11 | # 幻灯片大小 12 | 13 | Slidev 允许你通过 headmatter 中的 canvasWidth 和 aspectRatio 选项来设置幻灯片 canvas 的大小: 14 | 15 | ```md 16 | --- 17 | # 幻灯片的宽高比 18 | aspectRatio: 16/9 19 | # 幻灯片的实际宽度,以 px 为单位 20 | canvasWidth: 980 21 | --- 22 | 23 | # 以下为 slide 内容 24 | ``` 25 | 26 | 要缩放演示文稿中的多个幻灯片,你可以使用 `zoom` 选项: 27 | 28 | 29 | 30 | 要调整幻灯片上某些元素的大小,你可以使用 `Transform` 组件: 31 | 32 | 33 | -------------------------------------------------------------------------------- /custom/config-routes.md: -------------------------------------------------------------------------------- 1 | # 配置路由 2 | 3 | 4 | 5 | 将自定义页面添加到 Slidev。 6 | 7 | 8 | ## 用法 {#usage} 9 | 10 | 创建一份包含以下内容的 `./setup/routes.ts` 文件: 11 | 12 | 13 | ```ts twoslash 14 | import { defineRoutesSetup } from '@slidev/types' 15 | 16 | export default defineRoutesSetup((routes) => { 17 | return [ 18 | ...routes, 19 | { 20 | path: '/my-page', 21 | // ---cut-start--- 22 | // @ts-expect-error missing types 23 | // ---cut-end--- 24 | component: () => import('../pages/my-page.vue'), 25 | }, 26 | ] 27 | }) 28 | ``` 29 | 30 | 请参考 [Vue Router 文档](https://router.vuejs.org/) 来了解关于路由的更多细节。 31 | -------------------------------------------------------------------------------- /features/code-block-max-height.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/syntax#code-block 4 | tags: [代码块, 布局] 5 | description: | 6 | 为一个代码块设定最大高度并启用滚动。 7 | --- 8 | 9 | # 代码块最大高度 10 | 11 | 如果代码无法适应一个幻灯片,你可以使用 `maxHeight` 来设置一个固定的高度并启用滚动: 12 | 13 | ````md 14 | ```ts {2|3|7|12}{maxHeight:'100px'} 15 | function add( 16 | a: Ref | number, 17 | b: Ref | number 18 | ) { 19 | return computed(() => unref(a) + unref(b)) 20 | } 21 | /// ...很多行代码 22 | const c = add(1, 2) 23 | ``` 24 | ```` 25 | 26 | 请注意你可以使用 `{*}` 作为 的占位符: 27 | 28 | ````md 29 | ```ts {*}{maxHeight:'100px'} 30 | // ... 31 | ``` 32 | ```` 33 | -------------------------------------------------------------------------------- /uno.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, presetAttributify, presetUno, presetWebFonts, transformerDirectives } from 'unocss' 2 | 3 | export default defineConfig({ 4 | presets: [ 5 | presetUno(), 6 | presetAttributify(), 7 | presetWebFonts({ 8 | fonts: { 9 | mono: ['IBM Plex Mono', 'monospace'], 10 | }, 11 | }), 12 | ], 13 | transformers: [ 14 | transformerDirectives(), 15 | ], 16 | shortcuts: { 17 | 'bg-main': 'bg-white dark:bg-[#111]', 18 | }, 19 | theme: { 20 | colors: { 21 | primary: { 22 | DEFAULT: '#3AB9D4', 23 | deep: '#2082A6', 24 | }, 25 | }, 26 | }, 27 | }) 28 | -------------------------------------------------------------------------------- /custom/config-vue.md: -------------------------------------------------------------------------------- 1 | # 配置 Vue 实例 2 | 3 | 4 | 5 | Slidev 基于 [Vue 3](https://v3.vuejs.org/) 来渲染应用。你可以针对应用进行扩展,添加自定义插件或自定义配置等操作。 6 | 7 | 创建 `./setup/main.ts` 文件,其内容如下: 8 | 9 | 10 | 11 | ```ts twoslash 12 | import type { Plugin } from 'vue' 13 | declare const YourPlugin: Plugin 14 | // ---cut--- 15 | import { defineAppSetup } from '@slidev/types' 16 | 17 | export default defineAppSetup(({ app, router }) => { 18 | // Vue App 19 | app.use(YourPlugin) 20 | }) 21 | ``` 22 | 23 | 这也可以作为你 Slidev 应用程序的主入口,用于在应用启动前做一些初始化操作。 24 | 25 | 了解更多:[Vue 应用实例 API](https://v3.vuejs.org/api/application-api.html#component)。 26 | -------------------------------------------------------------------------------- /features/plantuml.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - Plant UML: https://plantuml.com/ 4 | - Plant UML 在线编辑器: https://plantuml.com/plantuml 5 | - Demo: https://sli.dev/demo/starter/12 6 | - features/mermaid 7 | tags: [图表] 8 | description: | 9 | 在 PlantUML 驱动下,通过文本描述创建图表。 10 | --- 11 | 12 | # PlantUML 图表 13 | 14 | 你可以在幻灯片中轻松地创建 PlantUML 图表,例如: 15 | 16 | ````md 17 | ```plantuml 18 | @startuml 19 | Alice -> Bob : Hello! 20 | @enduml 21 | ``` 22 | ```` 23 | 24 | 默认情况下,这部分源代码将被发送到 [https://www.plantuml.com/plantuml](https://www.plantuml.com/plantuml) 进行渲染。你也可以通过在 [headmatter](../custom/index#headmatter) 中设置 `plantUmlServer` 来设置自己的服务器。 25 | 26 | 参阅 [PlantUML官网](https://plantuml.com/) 了解更多信息。 27 | -------------------------------------------------------------------------------- /.vitepress/theme/styles/custom.css: -------------------------------------------------------------------------------- 1 | .icon-btn { 2 | --uno: inline-block cursor-pointer select-none important-outline-none; 3 | --uno: opacity-75 transition duration-200 ease-in-out align-middle rounded p-2; 4 | --uno: hover-(opacity-100 bg-gray-400 bg-opacity-10); 5 | } 6 | 7 | .icon-btn.disabled { 8 | --uno: opacity-25 pointer-events-none; 9 | } 10 | 11 | .inline-icon-btn { 12 | --uno: text-primary-deep; 13 | --uno: inline-block rounded p-0.5 text-2xl align-middle; 14 | --uno: border border-primary border-opacity-20 border-solid; 15 | } 16 | 17 | kbd { 18 | --uno: border-rounded bg-$vp-c-gray-1 bg-opacity-10 px-1 py-.5; 19 | } 20 | 21 | [data-tweet-id] { 22 | border-radius: 13px; 23 | } 24 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", 4 | "jsx": "preserve", 5 | "lib": ["DOM", "ESNext"], 6 | "baseUrl": ".", 7 | "module": "ESNext", 8 | "moduleResolution": "node", 9 | "resolveJsonModule": true, 10 | "types": [ 11 | "vite/client", 12 | "node" 13 | ], 14 | "strict": true, 15 | "strictNullChecks": true, 16 | "noUnusedLocals": true, 17 | "esModuleInterop": true, 18 | "forceConsistentCasingInFileNames": true, 19 | "skipLibCheck": true 20 | }, 21 | "include": [ 22 | "./*.ts", 23 | "./.vitepress/**/*.ts", 24 | "./.vitepress/**/*.vue" 25 | ], 26 | "exclude": ["**/dist/**", "node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /features/slide-hook.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/global-context 4 | tags: [客户端 api] 5 | description: | 6 | 用于侦听幻灯片生命周期的 hooks。 7 | --- 8 | 9 | # 幻灯片钩子 10 | 11 | Slidev 提供了一系列钩子来帮你侦听幻灯片的生命周期。 12 | 13 | ```ts twoslash 14 | import { onSlideEnter, onSlideLeave, useIsSlideActive } from '@slidev/client' 15 | 16 | const isActive = useIsSlideActive() 17 | 18 | onSlideEnter(() => { 19 | /* 将会在进入该幻灯片时被调用 */ 20 | }) 21 | 22 | onSlideLeave(() => { 23 | /* 将会在离开该幻灯片时被调用 */ 24 | }) 25 | ``` 26 | 27 | 你也可以使用 来访问其他有用的上下文信息。 28 | 29 | ::: warning 30 | 31 | 在幻灯片组件中,`onMounted` 和 `onUnmount` 钩子不可用,因为即使幻灯片未处于活动状态,组件实例也会被保留。请改用 `onSlideEnter` 和 `onSlideLeave`。 32 | 33 | ::: 34 | -------------------------------------------------------------------------------- /.vitepress/theme/components/DemoSlide.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 27 | -------------------------------------------------------------------------------- /features/block-frontmatter.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/syntax 4 | relates: 5 | - features/prettier-plugin 6 | tags: [语法] 7 | description: | 8 | 使用单独的 YAML 代码块作为 frontmatter 9 | --- 10 | 11 | # 代码块形式的 frontmatter 12 | 13 | 定义每个 slide 的 frontmatter 的默认方法很简洁,但是可能缺乏高亮显示与格式化的支持。要解决这个问题,你可以在 slide(单页幻灯片) 内容的开头用一个 YAML 代码块作为它的 frontmatter: 14 | 15 | ````md 16 | --- 17 | theme: default 18 | --- 19 | 20 | # Slide 1 21 | 22 | --- 23 | 24 | ```yaml 25 | layout: quote 26 | ``` 27 | 28 | # Slide 2 29 | 30 | --- 31 | 32 | # Slide 3 33 | ```` 34 | 35 | ::: warning 关于 headmatter 是什么 36 | 37 | 在 Slidev 中,headmatter 正是 Markdown 文件中通常所说的 “frontmatter”,大多数 markdown 编辑器和格式化工具都直接支持它。需要注意的是,不能用本页描述的 YAML 块来表示 headmatter。 38 | 39 | ::: 40 | -------------------------------------------------------------------------------- /features/code-block-line-numbers.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/syntax#code-block 4 | tags: [代码块] 5 | description: | 6 | 显示代码块中的行号。你可以选择为所有或者特定的代码块启用此特性。 7 | --- 8 | 9 | # Line Numbers 10 | 11 | 你可以通过在 headmatter 中设置 `lineNumbers: true` 来为幻灯片中的所有代码块启用行号,或者通过设置 `lines: true` 来单独为每个代码块启用行号。 12 | 13 | 你还可以通过 `{startLine: number}` 设置每个代码块的起始行,并相应地高亮显示这些行,其默认值为 1。 14 | 15 | ````md 16 | ```ts {6,7}{lines:true,startLine:5} 17 | function add( 18 | a: Ref | number, 19 | b: Ref | number 20 | ) { 21 | return computed(() => unref(a) + unref(b)) 22 | } 23 | ``` 24 | ```` 25 | 26 | 请注意你可以使用 `{*}` 作为 的占位符: 27 | 28 | ````md 29 | ```ts {*}{lines:true,startLine:5} 30 | // ... 31 | ``` 32 | ```` 33 | -------------------------------------------------------------------------------- /features/twoslash.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/syntax#code-block 4 | relates: 5 | - TwoSlash: https://twoslash.netlify.app/ 6 | since: v0.46.0 7 | tags: [代码块] 8 | description: | 9 | 一个强大的工具,用于在悬停或内联时渲染带有类型信息的 TypeScript 代码块。 10 | --- 11 | 12 | # TwoSlash 集成 13 | 14 | [TwoSlash](https://twoslash.netlify.app/) 是一个强大的工具,用于在悬停或内联时呈现带有类型信息的 TypeScript 代码块。它对于为 JavaScript/TypeScript 相关主题准备幻灯片非常有用。 15 | 16 | 要使用它,你可以在代码块的 语言id 中添加 `twoslash`: 17 | 18 | ````md 19 | ```ts twoslash 20 | import { ref } from 'vue' 21 | 22 | const count = ref(0) 23 | // ^? 24 | ``` 25 | ```` 26 | 27 | 它会被渲染为: 28 | 29 | ```ts twoslash 30 | import { ref } from 'vue' 31 | 32 | const count = ref(0) 33 | // ^? 34 | ``` 35 | 36 |
37 | -------------------------------------------------------------------------------- /resources/addon-gallery.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | --- 4 | 5 | 8 | 9 | # 插件合集 10 | 11 | 此处是 Slidev 超棒的插件合集。 12 | 13 | 可以阅读 来了解如何使用它们,或者阅读 来创建自己的插件。 14 | 15 | ## 官方插件 {#official-addons} 16 | 17 | 18 | 19 | 20 | 21 | ## 社区插件 {#community-addons} 22 | 23 | 下列是精选的社区插件。 24 | 25 | 26 | 27 | 28 | 29 | 30 | ## 更多插件 {#more-addons} 31 | 32 | [在 NPM 上](https://www.npmjs.com/search?q=keywords%3Aslidev-addon)查找所有已发布的插件。 33 | -------------------------------------------------------------------------------- /resources/theme-gallery.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | --- 4 | 5 | 8 | 9 | # 主题合集 10 | 11 | 此处是 Slidev 超棒的主题合集。 12 | 13 | 可以阅读 来了解如何使用它们,或者阅读 来创建你自己的主题。 14 | 15 | ## 官方主题 {#official-themes} 16 | 17 | 18 | 19 | 20 | 21 | ## 社区主题 {#community-themes} 22 | 23 | 下列是精选的社区主题。 24 | 25 | 26 | 27 | 28 | 29 | 30 | ## 更多主题 {#more-themes} 31 | 32 | [在 NPM 上](https://www.npmjs.com/search?q=keywords%3Aslidev-theme)查找所有已发布的主题。 33 | -------------------------------------------------------------------------------- /features/bundle-remote-assets.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - vite-plugin-remote-assets: https://github.com/antfu/vite-plugin-remote-assets 4 | tags: [构建] 5 | description: | 6 | 在构建时下载和打包所有远程资源。 7 | --- 8 | 9 | # 打包远程资源 10 | 11 | 就像你在 markdown 中做的那样,你可以使用指向远程或本地 URL 的图片。 12 | 13 | 对于远程的资源,内置的 [`vite-plugin-remote-assets`](https://github.com/antfu/vite-plugin-remote-assets) 会在首次运行时将它们缓存到磁盘上,来确保此后即使是较大的图片也能立刻加载。 14 | 15 | ```md 16 | ![远程图片](https://sli.dev/favicon.png) 17 | ``` 18 | 19 | 对于本地文件, 你可以将它们放入 [`public` 文件夹](/custom/directory-structure.html#public) 并且用 **前导斜杠** (例如, `/pic.png`, 而不是相对于当前文件的 `./pic.png`)来引用它们。 20 | 21 | ```md 22 | ![本地图片](/pic.png) 23 | ``` 24 | 25 | 如果你想应用自定义的大小或样式,你可以把它们转换为 `` 标签: 26 | 27 | ```html 28 | 29 | ``` 30 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | publish = ".vitepress/dist" 3 | command = "pnpm run build" 4 | 5 | [build.environment] 6 | NODE_VERSION = "20" 7 | PLAYWRIGHT_BROWSERS_PATH = "0" 8 | 9 | [[redirects]] 10 | from = "/new" 11 | to = "https://stackblitz.com/github/slidevjs/new?file=slides.md" 12 | status = 302 13 | force = true 14 | 15 | [[redirects]] 16 | from = "https://slidev.antfu.me/*" 17 | to = "https://sli.dev/:splat" 18 | status = 301 19 | force = true 20 | 21 | [[redirects]] 22 | from = "/demo/composable-vue/*" 23 | to = "https://demo.sli.dev/composable-vue" 24 | status = 301 25 | force = true 26 | 27 | [[redirects]] 28 | from = "/demo/starter/*" 29 | to = "https://demo.sli.dev/starter" 30 | status = 301 31 | force = true 32 | 33 | [[redirects]] 34 | from = "/*" 35 | to = "/index.html" 36 | status = 200 37 | -------------------------------------------------------------------------------- /features/build-with-pdf.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/exporting 4 | - guide/hosting 5 | relates: 6 | - CLI export 命令: /builtin/cli#export 7 | - Headmatter: /custom/#headmatter 8 | tags: [导出, 构建] 9 | description: | 10 | 在构建时生成可供下载的 PDF。 11 | --- 12 | 13 | # 在构建时生成 PDF 14 | 15 | 你可以在 headmatter 中使用以下配置,在已构建的幻灯片中提供一个可下载的 PDF: 16 | 17 | ```md 18 | --- 19 | download: true 20 | --- 21 | ``` 22 | 23 | Slidev 将在构建时生成一个 PDF 文件,并在构建的输出中显示一个下载按钮。 24 | 25 | 你也可以提供一个 PDF 的链接,这样 Slidev 将跳过渲染过程。 26 | 27 | ```md 28 | --- 29 | download: 'https://myslide.com/my-talk.pdf' 30 | --- 31 | ``` 32 | 33 | 这也可以通过 CLI 选项 `--download` (只接受 `boolean`值)来完成。 34 | 35 | ```bash 36 | $ slidev build --download 37 | ``` 38 | 39 | 启用下载选项时,你还可以通过以下方式提供导出选项: 40 | 41 | - [CLI 导出选项](/builtin/cli#export) 42 | - [Headmatter 导出选项](/custom/#frontmatter-configures) 43 | -------------------------------------------------------------------------------- /features/mdc.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - Nuxt 的 MDC 语法指南: https://content.nuxt.com/docs/files/markdown#mdc-syntax 4 | - markdown-it-mdc: https://github.com/antfu/markdown-it-mdc 5 | since: v0.43.0 6 | tags: [语法, 样式] 7 | description: | 8 | 一种强大的语法,用组件和样式增强 markdown 内容。 9 | --- 10 | 11 | # MDC 语法 12 | 13 | Slidev 支持可选的 [MDC (Markdown Components) 语法](https://content.nuxt.com/docs/files/markdown#mdc-syntax),由 [`markdown-it-mdc`](https://github.com/antfu/markdown-it-mdc) 驱动。 14 | 15 | 你可以通过在 markdown 文件的 frontmatter 中添加 `mdc:true` 来启用它。 16 | 17 | ```mdc 18 | --- 19 | mdc: true 20 | --- 21 | 22 | 这是一个 [红色的文本]{style="color:red"} :inline-component{prop="value"} 23 | 24 | ![](/image.png){width=500px lazy} 25 | 26 | ::block-component{prop="value"} 27 | **default** 插槽的内容 28 | :: 29 | ``` 30 | 31 | 请参阅 [MDC Syntax](https://content.nuxt.com/docs/files/markdown#mdc-syntax) 了解更多。 32 | -------------------------------------------------------------------------------- /features/frontmatter-merging.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/syntax#importing-slides 4 | - features/importing-slides 5 | tags: [语法] 6 | description: | 7 | 从不同的 Markdown 文件中合并 frontmatter。 8 | --- 9 | 10 | # 合并 Frontmatter 11 | 12 | 你可以为主入口点和外部 Markdown 页面提供 frontmatter。如果其中有相同的 key,**主入口点的 key 拥有更高的优先级**。例如: 13 | 14 | ::: code-group 15 | 16 | ```md [./slides.md] 17 | --- 18 | src: ./cover.md 19 | background: https://sli.dev/bar.png // [!code highlight] 20 | class: text-center 21 | --- 22 | ``` 23 | 24 | ```md [./cover.md] 25 | --- 26 | layout: cover 27 | background: https://sli.dev/foo.png // [!code highlight] 28 | --- 29 | 30 | # 封面 31 | 32 | 这是一个封面页 33 | ``` 34 | 35 | ::: 36 | 37 | 其效果最终与下述页面相同: 38 | ```md 39 | --- 40 | layout: cover 41 | background: https://sli.dev/bar.png // [!code highlight] 42 | class: text-center 43 | --- 44 | 45 | # 封面 46 | 47 | 这是一个封面页 48 | ``` 49 | -------------------------------------------------------------------------------- /guide/component.md: -------------------------------------------------------------------------------- 1 | # 组件指南 2 | 3 | Slidev 的一个最强大的功能是可以直接在幻灯片中使用 Vue 组件。这使得你可以轻松地创建交互式和动态内容。 4 | 5 | ## 使用组件 {#use} 6 | 7 | 基于 [`unplugin-vue-components`](https://github.com/unplugin/unplugin-vue-components),Slidev 允许你在幻灯片中直接使用 Vue 组件,而无需手动导入: 8 | 9 | ```md 10 | # My Slide 11 | 12 | 13 | ``` 14 | 15 | 该组件会从以下地方获取: 16 | 17 | - 内置组件。参见 [内置组件](../builtin/components)。 18 | - 由主题和插件提供。参见 。 19 | - `components` 目录中的自定义组件。参见下一节。 20 | 21 | ## 编写组件 {#write} 22 | 23 | 要创建一个自定义组件,只需在 `components` 目录中创建一个新的 Vue 文件: 24 | 25 | ```bash 26 | your-slidev/ 27 | ├── ... 28 | ├── slides.md 29 | └── components/ 30 | ├── ... 31 | └── MyComponent.vue 32 | ``` 33 | 34 | 参阅 [Vue 文档](https://cn.vuejs.org/guide/essentials/component-basics.html) 了解如何编写 Vue 组件。 35 | 36 | 也可以参见 来重用和分享你的组件。 37 | -------------------------------------------------------------------------------- /.vitepress/theme/components/Environment.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 25 | -------------------------------------------------------------------------------- /features/mermaid.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - Mermaid: http://mermaid.js.org/ 4 | - Mermaid Live Editor: https://mermaid.live/ 5 | - Demo Slide: https://sli.dev/demo/starter/12 6 | - features/plantuml 7 | tags: [图表] 8 | description: | 9 | 在 Mermaid 的驱动下,通过文本描述创建图表。 10 | --- 11 | 12 | # Mermaid.js 图表 13 | 14 | 你可以基于 [Mermaid](https://mermaid-js.github.io/mermaid),使用文本描述创建图表/图形。 15 | 16 | 被标记为 `mermaid` 的代码块将被转换为图表,例如: 17 | 18 | ````md 19 | ```mermaid 20 | sequenceDiagram 21 | Alice->John: Hello John, how are you? 22 | Note over Alice,John: A typical interaction 23 | ``` 24 | ```` 25 | 26 | 你还可以传递选项对象给 Mermaid,以指定缩放和主题。此处的语法是 JavaScript 对象字面量,你需要为字符串添加引号(`'`),并在键之间使用逗号(`,`)。 27 | 28 | ````md 29 | ```mermaid {theme: 'neutral', scale: 0.8} 30 | graph TD 31 | B[Text] --> C{Decision} 32 | C -->|One| D[Result 1] 33 | C -->|Two| E[Result 2] 34 | ``` 35 | ```` 36 | 37 | 参阅 [Mermaid 官网](http://mermaid.js.org/) 以获取更多细节。 38 | -------------------------------------------------------------------------------- /guide/write-layout.md: -------------------------------------------------------------------------------- 1 | # 编写布局 2 | 3 | > 请先阅读 。 4 | 5 | 只需在 `layouts` 目录中创建一个新的 Vue 文件即可创建自定义布局: 6 | 7 | ```bash 8 | your-slidev/ 9 | ├── ... 10 | ├── slides.md 11 | └── layouts/ 12 | ├── ... 13 | └── MyLayout.vue 14 | ``` 15 | 16 | 布局是 Vue 组件,因此你可以在其中使用 Vue 的所有功能。 17 | 18 | 在布局组件中,使用 ``(默认插槽)放置幻灯片内容: 19 | 20 | ```vue 21 | 22 | 27 | ``` 28 | 29 | 你也可以使用 [具名插槽](https://vuejs.org/guide/components/slots.html) 来创建更复杂的布局: 30 | 31 | ```vue 32 | 33 | 43 | ``` 44 | 45 | 并借助 使用它。 46 | -------------------------------------------------------------------------------- /.vitepress/theme/components/DemoEditor.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 40 | -------------------------------------------------------------------------------- /features/recording.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/ui#navigation-bar 4 | relates: 5 | - RecordRTC: https://github.com/muaz-khan/RecordRTC 6 | - WebRTC API: https://webrtc.org/ 7 | tags: [演讲者, 工具] 8 | description: | 9 | 在内置的摄像头调用及录屏功能加持下录制你的演示。 10 | --- 11 | 12 | # 录制工具 13 | 14 | Slidev 具有内置的摄像头视图和录制功能。它们使你可以轻松录制你的演示文稿,而无需在播放幻灯片时在其他录制工具之间切换。 15 | 16 | ## 摄像头视图 {#camera-view} 17 | 18 | 点击 [导航栏](../guide/ui#navigation-bar) 上的 按钮,将在演示文稿中显示你的摄像头视图。你可以拖动它,并使用右下角的把手来调整大小。尺寸和位置将持久化存储在 localStorage 中,因此,可以保证多次刷新后的展示一致,无需担心位置和大小丢失的问题。 19 | 20 | 21 | 22 | ## 开始录制 {#start-recording} 23 | 24 | 点击 [导航栏](../guide/ui#navigation-bar) 上的 按钮,将会弹出一个对话框。在此对话框中,你可以选择将你的摄像头视图嵌入到幻灯片中进行录制,也可以将它们分成两个视频文件。 25 | 26 | 此功能的实现得益于 [RecordRTC](https://github.com/muaz-khan/RecordRTC) 与 [WebRTC API](https://webrtc.org/)。 27 | 28 | ![](/screenshots/recording.png) 29 | -------------------------------------------------------------------------------- /.github/workflows/autosync.yml: -------------------------------------------------------------------------------- 1 | name: Auto Sync 2 | 3 | on: 4 | schedule: 5 | - cron: '0 0 * * *' # At 00:00. https://crontab.guru/ 6 | workflow_dispatch: # on button click 7 | 8 | jobs: 9 | sync: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | contents: write # 'write' access to repository contents 13 | steps: 14 | - name: Install git-filter-repo 15 | run: | 16 | sudo apt-get update 17 | sudo apt-get install -y git-filter-repo 18 | 19 | - name: Checkout upstram 20 | uses: actions/checkout@v2 21 | with: 22 | repository: slidevjs/slidev 23 | fetch-depth: 0 24 | 25 | - name: Extract docs 26 | run: git filter-repo --subdirectory-filter docs --force 27 | 28 | - name: Push changes 29 | uses: ad-m/github-push-action@v0.8.0 30 | with: 31 | github_token: ${{ secrets.GITHUB_TOKEN }} 32 | branch: refs/heads/upstream 33 | -------------------------------------------------------------------------------- /features/slide-scope-style.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - Vue 的 Scoped CSS: https://vue-loader.vuejs.org/guide/scoped-css.html 4 | - UnoCSS directives: https://unocss.dev/transformers/directives 5 | tags: [样式, 语法] 6 | description: | 7 | 定义仅在当前幻灯片生效的样式。 8 | --- 9 | 10 | # 幻灯片专属样式 11 | 12 | 你可以在 markdown 中使用 ` 23 | 24 | --- 25 | 26 | # 其他幻灯片不会受到影响 27 | ``` 28 | 29 | markdown中的 ` 45 | ``` 46 | -------------------------------------------------------------------------------- /features/direction-variant.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - UnoCSS Variants: https://unocss.dev/config/variants#variants 4 | since: v0.48.0 5 | tags: [导航, 样式] 6 | description: | 7 | 根据幻灯片放映方向应用不同的样式和动画。 8 | --- 9 | 10 | # 基于导航方向的样式 11 | 12 | 你可能希望根据滑动幻灯片的方向来应用不同的类。 `.slidev-nav-go-forward` 或 `.slidev-nav-go-backward` 类将在放映时相应应用于幻灯片容器, 因而你可以用他们来实现不同的样式或动画: 13 | 14 | ```css 15 | /* 示例:向前切换幻灯片使延时,向后时不生效 */ 16 | .slidev-nav-go-forward .slidev-vclick-target { 17 | transition-delay: 500ms; 18 | } 19 | .slidev-nav-go-backward .slidev-vclick-target { 20 | transition-delay: 0; 21 | } 22 | ``` 23 | 24 | 为了使其更易使用,我们也为此提供了一些 [UnoCSS variants](https://github.com/slidevjs/slidev/blob/6adcf2016b8fb0cab65cf150221f1f67a76a2dd8/packages/client/uno.config.ts#L32-L38)。你可以对任何 UnoCSS 类使用 `forward:` 或 `backward:` 前缀,来仅在特定播放方向上启用它们: 25 | 26 | ```html 27 |
元素
// [!code --] 28 |
元素
// [!code ++] 29 | ``` 30 | 31 | 在上方的示例中,动画仅在向前切换幻灯片时延迟。 32 | -------------------------------------------------------------------------------- /.vitepress/theme/components/LandingPage.vue: -------------------------------------------------------------------------------- 1 | 25 | -------------------------------------------------------------------------------- /.vitepress/addons.ts: -------------------------------------------------------------------------------- 1 | import type { ThemeInfo } from './themes' 2 | 3 | export type AddonInfo = Omit 4 | 5 | export const official: AddonInfo[] = [ 6 | { 7 | id: '', 8 | link: '#', 9 | name: 'Work in Progress', 10 | description: '', 11 | author: { 12 | name: '', 13 | }, 14 | }, 15 | ] 16 | 17 | export const community: AddonInfo[] = [ 18 | { 19 | id: 'slidev-addon-tldraw', 20 | name: 'tldraw for Slidev', 21 | description: 'Embed tldraw diagrams directly in Slidev, with in-slide editing support', 22 | author: { 23 | name: 'Albert Brand', 24 | link: 'https://github.com/AlbertBrand', 25 | }, 26 | repo: 'https://github.com/AlbertBrand/slidev-addon-tldraw', 27 | }, 28 | // Add yours here! 29 | { 30 | id: '', 31 | link: 'https://github.com/slidevjs/slidev/edit/main/docs/.vitepress/addons.ts', 32 | name: 'Yours?', 33 | description: '点击此处分享你的插件', 34 | author: { 35 | name: '', 36 | }, 37 | }, 38 | ] 39 | -------------------------------------------------------------------------------- /resources/learning.md: -------------------------------------------------------------------------------- 1 | # 学习资源 2 | 3 | ## English 4 | 5 | ### Videos 6 | 7 | - [Slidev - one of the best presentation software and it is free!](https://www.youtube.com/watch?v=oSgM6GoSwyY) - by [Federico Tartarini](https://www.youtube.com/@FedericoTartarini) 8 | 9 | ### Articles 10 | 11 | - [Tips To Turn R Markdown Into Slidev Presentation](https://yutani.rbind.io/post/2021-06-05-tips-to-turn-r-markdown-into-slidev-presentation/) by Hiroaki Yutani 12 | 13 | ## 中文 14 | 15 | - [Slidev:一个用Markdown写slides的神器](https://zhuanlan.zhihu.com/p/372729473) by [梦里风林](https://www.zhihu.com/people/meng-li-feng-lin) 16 | - [神器!这款开源项目可以让你使用 Markdown 来做 PPT!](https://zhuanlan.zhihu.com/p/377567327) by [Github掘金计划](https://www.zhihu.com/people/github-stars) 17 | 18 | ## 日本語 19 | 20 | - [開発者のためのスライド作成ツール Slidev がすごい](https://zenn.dev/ryo_kawamata/articles/introduce-slidev) by [ryo_kawamata](https://zenn.dev/ryo_kawamata) 21 | - [Markdownでオシャレなスライドを作るSli.dev](https://qiita.com/e99h2121/items/a115f8865a0dc21bb462) by [Nobuko YAMADA](https://qiita.com/e99h2121) 22 | -------------------------------------------------------------------------------- /custom/config-shortcuts.md: -------------------------------------------------------------------------------- 1 | # 配置快捷键 {#configure-shortcuts} 2 | 3 | 4 | 5 | ## 开始使用 {#getting-started} 6 | 7 | 创建一份包含以下内容的 `./setup/shortcuts.ts` 文件: 8 | 9 | ```ts twoslash 10 | import type { NavOperations, ShortcutOptions } from '@slidev/types' 11 | import { defineShortcutsSetup } from '@slidev/types' 12 | 13 | export default defineShortcutsSetup((nav: NavOperations, base: ShortcutOptions[]) => { 14 | return [ 15 | ...base, // 保留已有的快捷键 16 | { 17 | key: 'enter', 18 | fn: () => nav.next(), 19 | autoRepeat: true, 20 | }, 21 | { 22 | key: 'backspace', 23 | fn: () => nav.prev(), 24 | autoRepeat: true, 25 | }, 26 | ] 27 | }) 28 | ``` 29 | 30 | 在配置时,你可以添加或者一些自定义的快捷键。例如,上面的配置为 enter 绑定了 `前进` 操作,为 backspace 绑定了 `后退` 操作。 31 | 32 | 有关默认快捷键和导航操作,请参阅 [导航操作](../guide/ui#navigation-actions) 部分。 33 | 34 | ## 键盘绑定格式 35 | 36 | 每个快捷键的 `key` 可以是字符串(例如 `Shift+Ctrl+a`)或 Vue `computed` 形式的布尔值。请参考 VueUse 的 [`useMagicKeys`](https://vueuse.org/core/useMagicKeys/) 以获取更多细节。 37 | -------------------------------------------------------------------------------- /guide/write-addon.md: -------------------------------------------------------------------------------- 1 | # 编写插件 2 | 3 | > 请先阅读 。 4 | 5 | 每个演示文稿只能有一个主题,但可以安装多个插件。 6 | 7 | ## 插件能力 {#capability} 8 | 9 | 理论上,插件可以实现主题的所有功能。但是,插件更像是扩展 Slidev 功能的插件。 10 | 11 | 建议在插件中实现以下功能之一或多个: 12 | 13 | - 提供自定义组件 14 | - 提供 _新的_ 布局 15 | - 提供新的代码片段 16 | - 提供新的代码运行器 17 | - 配置 UnoCSS、Vite 等工具 18 | 19 | 但是,不建议在插件中实现以下功能,这些功能可能更适合 [实现为主题](./write-theme): 20 | 21 | - 通配符全局样式 22 | - 覆盖现有布局 23 | - 覆盖配置 24 | - 其他可能与主题和其他插件不兼容的功能 25 | 26 | 一个插件可以像主题一样指定它所需的 Slidev 版本。 27 | 28 | ## 预览插件 {#previewing} 29 | 30 | 与主题类似,你可以通过以下 `./slides.md` 文件预览你的插件: 31 | 32 | ```md 33 | --- 34 | addons: 35 | - ./ 36 | --- 37 | ``` 38 | 39 | ## 发布插件 {#publishing} 40 | 41 | 当发布插件时,非 JS 文件(如 `.vue` 和 `.ts` 文件)可以直接发布而无需编译。Slidev 在使用插件时会自动编译它们。 42 | 43 | 插件应遵循以下约定: 44 | 45 | - 包名应以 `slidev-addon-` 开头。例如,`slidev-addon-name` 或 `@scope/slidev-addon-name` 46 | - 在 `package.json` 的 `keywords` 字段中添加 `"slidev-addon"` 和 `"slidev"` 47 | 48 | 主题可以在本地使用而无需发布到 NPM。如果你的插件仅供个人使用,你可以将其简单地用作本地插件,或者将其发布为私有作用域包。但是,如果你想与他人分享,建议将其发布到 NPM。 49 | -------------------------------------------------------------------------------- /features/monaco-editor.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/syntax#code-block 4 | relates: 5 | - Monaco Editor: https://microsoft.github.io/monaco-editor/ 6 | - Configure Monaco Editor: /custom/config-monaco 7 | tags: [代码块, 编辑器] 8 | description: | 9 | 将代码块变为功能齐全的编辑器,或者在两个代码块间生成 diff。 10 | --- 11 | 12 | # Monaco 编辑器 13 | 14 | 15 | 16 | 每当你想在演示文稿中做一些修改时,只需在 语言id 后添加 `{monaco}` ——它就会把这个块变成一个功能齐全的 Monaco 编辑器! 17 | 18 | ````md 19 | ```ts {monaco} 20 | console.log('HelloWorld') 21 | ``` 22 | ```` 23 | 24 | 了解有关 [配置 Monaco](/custom/config-monaco) 的更多信息。 25 | 26 | ## Diff Editor 27 | 28 | Monaco 还可以在两个代码快间生成差异。你可以用 `{monaco-diff}` 将代码块变为一个 [Monaco diff 编辑器](https://microsoft.github.io/monaco-editor/playground.html?source=v0.36.1#example-creating-the-diffeditor-multi-line-example)。你需要用 `~~~` 来分隔原始代码与修改后的代码。 29 | 30 | ````md 31 | ```ts {monaco-diff} 32 | console.log('Original text') 33 | ~~~ 34 | console.log('Modified text') 35 | ``` 36 | ```` 37 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import Icons from 'unplugin-icons/vite' 3 | import IconsResolver from 'unplugin-icons/resolver' 4 | import Components from 'unplugin-vue-components/vite' 5 | import Inspect from 'vite-plugin-inspect' 6 | import UnoCSS from 'unocss/vite' 7 | 8 | export default defineConfig({ 9 | optimizeDeps: { 10 | exclude: [ 11 | 'vue-demi', 12 | '@vueuse/shared', 13 | '@vueuse/core', 14 | ], 15 | }, 16 | server: { 17 | hmr: { 18 | overlay: false, 19 | }, 20 | }, 21 | plugins: [ 22 | Components({ 23 | dirs: [ 24 | './.vitepress/theme/components', 25 | './node_modules/@slidev/client/builtin', 26 | ], 27 | extensions: ['vue', 'md'], 28 | include: [/\.vue$/, /\.vue\?vue/, /\.md$/, /\.md\?vue/], 29 | resolvers: [ 30 | IconsResolver({ 31 | prefix: '', 32 | }), 33 | ], 34 | }), 35 | Icons({ 36 | defaultStyle: 'display: inline-block;', 37 | }), 38 | Inspect(), 39 | UnoCSS(), 40 | ], 41 | }) 42 | -------------------------------------------------------------------------------- /features/import-snippet.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - features/monaco-write 4 | - features/monaco-editor 5 | since: v0.47.0 6 | tags: [代码块, 语法] 7 | description: | 8 | 将文件中的代码片段导入你的幻灯片。 9 | --- 10 | 11 | # 引入代码片段 12 | 13 | 你可以通过以下语法从现有文件导入代码段: 14 | 15 | ```md 16 | <<< @/snippets/snippet.js 17 | ``` 18 | 19 | ::: tip 20 | “@”的值对应于包的根目录。为了与 Monaco 编辑器兼容,建议将代码段放在 `@/snippets` 中。或者,你也可以从相对路径导入。 21 | ::: 22 | 23 | 你还可以使用 [VS Code 代码折叠语法](https://code.visualstudio.com/docs/editor/codebasics#_folding) 来只引用代码文件的相应部分: 24 | 25 | 26 | ```md 27 | <<< @/snippets/snippet.js#region-name 28 | ``` 29 | 30 | 若要指定导入代码的语言,你可以在引入后添加语言名称: 31 | 32 | ```md 33 | <<< @/snippets/snippet.js ts 34 | ``` 35 | 36 | 导入的代码块也支持普通代码块的功能,如 [逐行高亮](#line-highlighting) 和 [Monaco 编辑器](#monaco-editor): 37 | 38 | ```md 39 | <<< @/snippets/snippet.js {2,3|5}{lines:true} 40 | <<< @/snippets/snippet.js ts {monaco}{height:200px} 41 | ``` 42 | 43 | 请注意你可以使用 `{*}` 作为 的占位符: 44 | 45 | 46 | 47 | ```md 48 | <<< @/snippets/snippet.js {*}{lines:true} 49 | ``` 50 | -------------------------------------------------------------------------------- /features/monaco-run.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - features/monaco-editor 4 | - guide/animations 5 | relates: 6 | - 自定义代码运行器: /custom/config-code-runners 7 | since: v0.48.0 8 | tags: [代码块, 编辑器] 9 | description: | 10 | 直接在编辑器中运行代码并获取结果。 11 | --- 12 | 13 | # Monaco 代码运行器 14 | 15 | Slidev 还提供了 Monaco Runner 编辑器,它允许你直接在编辑器中运行代码并查看结果。使用`{monaco-run}`将块转换为 Monaco Runner 编辑器。 16 | 17 | ````md 18 | ```ts {monaco-run} 19 | function distance(x: number, y: number) { 20 | return Math.sqrt(x ** 2 + y ** 2) 21 | } 22 | console.log(distance(3, 4)) 23 | ``` 24 | ```` 25 | 26 | 它为编辑器提供了一个 “运行” 按钮,并在代码块正下方显示代码执行的结果。你也可以修改代码,结果将实时更新。 27 | 28 | 默认情况下,加载幻灯片时,它将自动运行代码;如果你想显式触发运行,你可以设置`{autorun:false}`。 29 | 30 | 31 | ````md 32 | ```ts {monaco-run} {autorun:false} 33 | console.log('请点击右上角的运行按钮') 34 | ``` 35 | ```` 36 | 37 | 如果你只想在某些点击中显示输出,你可以使用 `showOutputAt` prop。该值与`v-click` 相同。 38 | 39 | ````md 40 | ```ts {monaco-run} {showOutputAt:'+1'} 41 | console.log('一步动画后后显示该结果') 42 | ``` 43 | ```` 44 | 45 | 目前,Slidev 内置支持运行 JavaScript 和 TypeScript 代码。若要运行自定义语言,请参阅 [自定义代码运行程序](/custom/config-code-runners)。 46 | -------------------------------------------------------------------------------- /features/importing-slides.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - features/frontmatter-merging 4 | tags: [语法] 5 | description: | 6 | 将你的幻灯片分割成多个文件来获得更好的可复用性和组织性。 7 | --- 8 | 9 | # 引入幻灯片 10 | 11 | 你可以将`slides.md`拆分为多个文件,以提高可复用性和组织性。为此,你可以使用 frontmatter 中的 `src` 选项指定外部 Markdown 文件的路径。例如: 12 | 13 | ::: code-group 14 | 15 | 16 | 17 | ```md [./slides.md] 18 | # 标题 19 | 20 | 这是一个普通的页面 21 | 22 | --- 23 | src: ./pages/toc.md // [!code highlight] 24 | --- 25 | 26 | 27 | 28 | 这里的内容将被忽略 29 | 30 | --- 31 | 32 | # 第四页 33 | 34 | 另一个正常的页面 35 | 36 | --- 37 | src: ./pages/toc.md # Reuse the same file // [!code highlight] 38 | --- 39 | ``` 40 | 41 | ```md [./pages/toc.md] 42 | # 目录 43 | 44 | Part 1 45 | 46 | --- 47 | 48 | # 目录 49 | 50 | Part 2 51 | ``` 52 | 53 | ::: 54 | 55 | ## 导入特定幻灯片 56 | 57 | 要在另一个 Markdown 文件中复用一些幻灯片,你可以使用导入路径的哈希部分: 58 | 59 | ```md 60 | --- 61 | src: ./another-presentation.md#2,5-7 62 | --- 63 | ``` 64 | 65 | 这会从 `./another-presentation.md` 中导入第 2,5,6,7 页。 66 | 67 | ## Frontmatter 合并 68 | 69 | 70 | -------------------------------------------------------------------------------- /custom/config-context-menu.md: -------------------------------------------------------------------------------- 1 | # 配置右键菜单 2 | 3 | 4 | 5 | 自定义 Slidev 的右键菜单项。 6 | 7 | 创建包含以下内容的 `./setup/context-menu.ts` 文件: 8 | 9 | 10 | 11 | ```ts twoslash 12 | // ---cut--- 13 | import { defineContextMenuSetup } from '@slidev/types' 14 | import { useNav } from '@slidev/client' 15 | import { computed } from 'vue' 16 | // ---cut-start--- 17 | // @ts-expect-error missing types 18 | // ---cut-end--- 19 | import Icon3DCursor from '~icons/carbon/3d-cursor' 20 | 21 | export default defineContextMenuSetup((items) => { 22 | const { isPresenter } = useNav() 23 | return computed(() => [ 24 | ...items.value, 25 | { 26 | small: false, 27 | icon: Icon3DCursor, // 当 `small` 为 `true` 时,仅显示图标 28 | label: 'Custom Menu Item', // 也可以是 Vue 组件 29 | action() { 30 | alert('Custom Menu Item Clicked!') 31 | }, 32 | disabled: isPresenter.value, 33 | }, 34 | ]) 35 | }) 36 | ``` 37 | 38 | 以上代码将在右键菜单中添加一个新的菜单项。 39 | 40 | 若要全局禁用右键菜单,请在 frontmatter 中设置 `contextMenu` 为 `false`。`contextMenu` 也可以设置为 `dev` 或 `build`,以仅在开发或构建模式下启用右键菜单。 41 | -------------------------------------------------------------------------------- /features/rough-marker.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/animations 4 | relates: 5 | - Rough Notation: https://github.com/linkstrifer/react-rough-notation 6 | since: v0.48.0 7 | tags: [绘图, 动画] 8 | description: | 9 | 集成 Rough Notation 来在你的幻灯片中标记或突出显示元素。 10 | --- 11 | 12 | # Rough Markers 13 | 14 | Slidev 集成了 [Rough Notation](https://github.com/linkstrifer/react-rough-notation) 许在幻灯片中标记或高亮元素。 15 | 16 | --- 17 | 18 | ### `v-mark` 指令 19 | 20 | Rough Notation 集成了 `v-mark` 指令。 21 | 22 | #### 类型 23 | 24 | `v-mark.underline` 进行下划线标记, `v-mark.circle` 进行圆圈标记,以此类推。默认为 `underline`。 25 | 26 | #### Color 27 | 28 | `v-mark.red` 会将标记设定为 `red`. 支持 UnoCSS 的内置颜色主题。对于自定义颜色,请使用对象语法 `v-mark="{ color: '#234' }"`。 29 | 30 | #### 点击事件 31 | 32 | `v-mark` 的工作方式类似于 `v-click` 并会在点击后触发。 与 `v-click`相同, 它允许你传递一个自定义的点击值,比如`v-mark="5"` 或 `v-mark="'+1'"`。 33 | 34 | #### 选项 35 | 36 | 你还可以向 `v-mark` 传递一个对象来制定选项,例如: 37 | 38 | ```vue 39 | 40 | 重要的文字 41 | 42 | ``` 43 | 44 | #### 预览 45 | 46 | 47 | -------------------------------------------------------------------------------- /features/prettier-plugin.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - features/block-frontmatter 4 | - 插件的 GitHub 仓库: https://github.com/slidevjs/prettier-plugin 5 | - Prettier.js 官网: https://prettier.io/ 6 | tags: [编辑器] 7 | description: | 8 | 使用 Prettier.js 插件来格式化你的幻灯片。 9 | --- 10 | 11 | # Prettier.js 插件 12 | 13 | Slidev 的语法可能与 [Prettier](https://prettier.io/) 的默认 markdown 解析器不兼容. 为了解决这个问题,Slidev 提供了一个 Prettier 插件来格式化你的幻灯片。你可以在支持 Prettier 的任何编辑器中使用它。 14 | 15 | ## 1. 安装 16 | 17 | ::: code-group 18 | 19 | ```bash [npm] 20 | npm i -D prettier prettier-plugin-slidev 21 | ``` 22 | 23 | ```bash [pnpm] 24 | pnpm i -D prettier prettier-plugin-slidev 25 | ``` 26 | 27 | ```bash [yarn] 28 | yarn add -D prettier prettier-plugin-slidev 29 | ``` 30 | 31 | ::: 32 | 33 | ## 2. 激活插件 34 | 35 | 创建或者修改你的 [prettier 配置文件](https://prettier.io/docs/en/configuration) 来激活插件: 36 | 37 | ```json 38 | { 39 | "overrides": [ 40 | { 41 | "files": ["slides.md", "pages/*.md"], 42 | "options": { 43 | "parser": "slidev", 44 | "plugins": ["prettier-plugin-slidev"] 45 | } 46 | } 47 | ] 48 | } 49 | ``` 50 | 51 | 请注意,仅指定 `plugins` 是不够的,因为 Slidev 和常见的 Markdown 文件共享相同的文件扩展名 `.md`。 52 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "type": "module", 4 | "version": "0.49.29", 5 | "private": true, 6 | "packageManager": "pnpm@9.9.0", 7 | "scripts": { 8 | "dev": "vitepress", 9 | "build": "vitepress build", 10 | "preview": "vitepress preview" 11 | }, 12 | "dependencies": { 13 | "@antfu/utils": "^0.7.10", 14 | "@vueuse/core": "^10.11.0", 15 | "typeit": "8.1.0" 16 | }, 17 | "devDependencies": { 18 | "@iconify/json": "^2.2.230", 19 | "@shikijs/vitepress-twoslash": "^1.11.1", 20 | "@slidev/client": "latest", 21 | "@slidev/parser": "latest", 22 | "@slidev/theme-default": "latest", 23 | "@slidev/types": "latest", 24 | "@types/fs-extra": "^11.0.4", 25 | "@types/node": "^20.14.11", 26 | "@unocss/reset": "^0.61.5", 27 | "fast-glob": "^3.3.2", 28 | "fs-extra": "^11.2.0", 29 | "gray-matter": "^4.0.3", 30 | "markdown-it": "^14.1.0", 31 | "shiki": "^1.11.1", 32 | "typescript": "^5.5.4", 33 | "unocss": "^0.61.5", 34 | "unplugin-icons": "^0.19.0", 35 | "unplugin-vue-components": "^0.27.3", 36 | "vite-plugin-inspect": "^0.8.5", 37 | "vitepress": "^1.3.1" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /features/line-highlighting.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/syntax#code-block 4 | - guide/animations 5 | tags: [代码块, 动画] 6 | description: | 7 | 根据点击次数高亮显示代码块中的特定行。 8 | --- 9 | 10 | # 高亮代码行 11 | 12 | 要想高亮特定行,只需在括号 `{}` 中添加行号即可。行号默认从 1 开始。 13 | 14 | ````md 15 | ```ts {2,3} 16 | function add( 17 | a: Ref | number, 18 | b: Ref | number 19 | ) { 20 | return computed(() => unref(a) + unref(b)) 21 | } 22 | ``` 23 | ```` 24 | 25 | ## 动态逐行高亮 26 | 27 | 要更改多次点击中高亮的内容,可以使用 `|` 分隔每个阶段: 28 | 29 | ````md 30 | ```ts {2-3|5|all} 31 | function add( 32 | a: Ref | number, 33 | b: Ref | number 34 | ) { 35 | return computed(() => unref(a) + unref(b)) 36 | } 37 | ``` 38 | ```` 39 | 40 | 这会首先高亮 `a: Ref | number` and `b: Ref | number`,然后在点击一次后是 `return computed(() => unref(a) + unref(b))` ,最终高亮整个块。 41 | 42 | 你可以将行号设置为 `hide` 以隐藏代码块,或设置为 `none` 以不突出显示任何行: 43 | 44 | ````md 45 | ```ts {hide|none} 46 | function add( 47 | a: Ref | number, 48 | b: Ref | number 49 | ) { 50 | return computed(() => unref(a) + unref(b)) 51 | } 52 | ``` 53 | ```` 54 | 55 | ::: tip 56 | 你可以在 [点击动画指南](/guide/animations#positioning) 中了解更多。 57 | ::: 58 | -------------------------------------------------------------------------------- /custom/config-mermaid.md: -------------------------------------------------------------------------------- 1 | # 配置 Mermaid {#configure-mermaid} 2 | 3 | 4 | 5 | 创建一份包含以下内容的 `./setup/mermaid.ts` 文件: 6 | 7 | ```ts twoslash 8 | import { defineMermaidSetup } from '@slidev/types' 9 | 10 | export default defineMermaidSetup(() => { 11 | return { 12 | theme: 'forest', 13 | } 14 | }) 15 | ``` 16 | 17 | 返回值应该是 [Marimaid.js](https://mermaid.js.org/) 的自定义配置。完整配置列表请参考其类型定义及 [Mermaid 的文档](http://mermaid.js.org/config/schema-docs/config.html)。 18 | 19 | ## 自定义主题/样式 {#custom-theme-styles} 20 | 21 | 如果你想要创建自定义的 Mermaid 主题或样式,可以通过定义 `themeVariables` 实现,如下例所示: 22 | 23 | ```ts twoslash 24 | import { defineMermaidSetup } from '@slidev/types' 25 | 26 | export default defineMermaidSetup(() => { 27 | return { 28 | theme: 'base', 29 | themeVariables: { 30 | // 主题变量 31 | noteBkgColor: '#181d29', 32 | noteTextColor: '#F3EFF5cc', 33 | noteBorderColor: '#404551', 34 | 35 | // 序列图变量 36 | actorBkg: '#0E131F', 37 | actorBorder: '#44FFD2', 38 | actorTextColor: '#F3EFF5', 39 | actorLineColor: '#F3EFF5', 40 | signalColor: '#F3EFF5', 41 | signalTextColor: '#F3EFF5', 42 | } 43 | } 44 | }) 45 | ``` 46 | 47 | 你可以在 [Mermaid 主题配置](https://mermaid.js.org/config/theming.html) 上找到全部的主题变量。 48 | -------------------------------------------------------------------------------- /custom/config-transformers.md: -------------------------------------------------------------------------------- 1 | # 配置自定义语法 2 | 3 | 4 | 5 | Slidev 支持自定义 Markdown 语法。通过这种方式,你可以为你的幻灯片添加自定义的 Markdown 语法,以及自定义代码块的渲染。 6 | 7 | 首先,创建一个 `/setup/transformers.ts` 文件,内容如下: 8 | 9 | ````ts twoslash 10 | import type { MarkdownTransformContext } from '@slidev/types' 11 | import { defineTransformersSetup } from '@slidev/types' 12 | 13 | function myCodeblock(ctx: MarkdownTransformContext) { 14 | console.log('在整个幻灯片中的索引:', ctx.slide.index) 15 | ctx.s.replace( 16 | /^```myblock *(\{[^\n]*\})?\n([\s\S]+?)\n```/gm, 17 | (full: string, options = '', code = '') => { 18 | return `...` 19 | }, 20 | ) 21 | } 22 | 23 | export default defineTransformersSetup(() => { 24 | return { 25 | pre: [], 26 | preCodeblock: [myCodeblock], 27 | postCodeblock: [], 28 | post: [], 29 | } 30 | }) 31 | ```` 32 | 33 | 返回值是包含 `pre`、`preCodeblock`、`postCodeblock` 和 `post` 四个可选字段,每个字段的值是函数数组,将被调用以转换 Markdown 内容。它们的调用顺序为: 34 | 35 | 1. 来自你的项目的 `pre` 36 | 2. 来自插件和主题的 `pre` 37 | 3. 导入代码片段语法和 Shiki magic move 38 | 4. 来自你的项目的 `preCodeblock` 39 | 5. 来自插件和主题的 `preCodeblock` 40 | 6. 内置的 Mermaid、Monaco 和 PlantUML 等特殊代码块 41 | 7. 来自插件和主题的 `postCodeblock` 42 | 8. 来自你的项目的 `postCodeblock` 43 | 9. 其他内置的自定义语法,如代码块包装 44 | 10. 来自插件和主题的 `post` 45 | 11. 来自你的项目的 `post` 46 | -------------------------------------------------------------------------------- /features/slot-sugar.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - Vue's 具名插槽: https://cn.vuejs.org/guide/components/slots#named-slots 4 | tags: [布局, 语法] 5 | description: | 6 | 针对布局中具名插槽的语法糖。 7 | --- 8 | 9 | # 布局插槽语法糖 10 | 11 | 一些布局可以通过 [Vue 具名插槽](https://vuejs.org/guide/components/slots.html) 提供多个可插入的位点。 12 | 13 | 例如,在 [`two-cols` 布局](https://github.com/slidevjs/slidev/blob/main/packages/client/layouts/two-cols.vue)中,你可以创建一左一右的双栏布局。 14 | 15 | ```md 16 | --- 17 | layout: two-cols 18 | --- 19 | 20 | 27 | 34 | ``` 35 | 36 |
37 |
38 |

39 |

这会在左边显示

40 |
41 |
42 |

43 |

这会在右边显示

44 |
45 |
46 | 47 | 我们还为插槽名称提供了一个简写语法糖 `::name::`。下面的示例与前面的示例完全相同: 48 | 49 | ```md 50 | --- 51 | layout: two-cols 52 | --- 53 | 54 | # 左 55 | 56 | 这会在左边显示 57 | 58 | ::right:: 59 | 60 | # 右 61 | 62 | 这会在右边显示 63 | ``` 64 | 65 | 你还可以明确指定默认插槽,并按自定义顺序排列。 66 | 67 | ```md 68 | --- 69 | layout: two-cols 70 | --- 71 | 72 | ::right:: 73 | 74 | # 右 75 | 76 | 这会在右边显示 77 | 78 | ::default:: 79 | 80 | # 左 81 | 82 | 这会在左边显示 83 | ``` 84 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | // Enable the ESlint flat config support 3 | "eslint.experimental.useFlatConfig": true, 4 | 5 | // Disable the default formatter, use eslint instead 6 | "prettier.enable": false, 7 | "editor.formatOnSave": false, 8 | 9 | // Auto fix 10 | "editor.codeActionsOnSave": { 11 | "source.fixAll.eslint": "explicit", 12 | "source.organizeImports": "never" 13 | }, 14 | 15 | // Silent the stylistic rules in you IDE, but still auto fix them 16 | "eslint.rules.customizations": [ 17 | { "rule": "style/*", "severity": "off" }, 18 | { "rule": "format/*", "severity": "off" }, 19 | { "rule": "*-indent", "severity": "off" }, 20 | { "rule": "*-spacing", "severity": "off" }, 21 | { "rule": "*-spaces", "severity": "off" }, 22 | { "rule": "*-order", "severity": "off" }, 23 | { "rule": "*-dangle", "severity": "off" }, 24 | { "rule": "*-newline", "severity": "off" }, 25 | { "rule": "*quotes", "severity": "off" }, 26 | { "rule": "*semi", "severity": "off" } 27 | ], 28 | 29 | // Enable eslint for all supported languages 30 | "eslint.validate": [ 31 | "javascript", 32 | "javascriptreact", 33 | "typescript", 34 | "typescriptreact", 35 | "vue", 36 | "html", 37 | "markdown", 38 | "json", 39 | "jsonc", 40 | "yaml", 41 | "toml" 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /features/drawing.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/ui#navigation-bar 4 | relates: 5 | - drauu: https://github.com/antfu/drauu 6 | tags: [绘图] 7 | description: | 8 | 在幻灯片中绘图和批注。 9 | --- 10 | 11 | # 绘图与批注 12 | 13 | 我们基于 [drauu](https://github.com/antfu/drauu) 实现了绘图和批注的功能,可用于轻松绘制和注释幻灯片。 14 | 15 | 首先,点击 [导航栏](../guide/ui#navigation-bar) 中的 图标来打开绘图工具栏。它也可以在 [演讲者模式](/guide/ui#presenter-mode) 中使用。你创建的绘图和批注都会在所有实例中实时**自动同步**起来。 16 | 17 | 18 | 19 | ## 与触控笔一同使用 20 | 21 | 当在平板电脑上使用触控笔时(例如,带有 Apple Pencil 的 iPad),Slidev 可以智能地检测输入类型。你可以直接用笔在幻灯片上绘图,而无需打开绘图模式,同时你的手指或鼠标可以控制导航。 22 | 23 | ## 对绘图进行持久化 24 | 25 | 以下 frontmatter 中的配置可以把你的绘图作为 SVG 保存在 `.slidev/drawings` 目录下,并把它们放入你导出的 pdf 或者部署的网站中。 26 | 27 | ```md 28 | --- 29 | drawings: 30 | persist: true 31 | --- 32 | ``` 33 | 34 | ## 禁用绘图 35 | 36 | 完全禁用: 37 | 38 | ```md 39 | --- 40 | drawings: 41 | enabled: false 42 | --- 43 | ``` 44 | 45 | 仅在开发环境可用: 46 | 47 | ```md 48 | --- 49 | drawings: 50 | enabled: dev 51 | --- 52 | ``` 53 | 54 | 仅在演讲者模式可用: 55 | 56 | ```md 57 | --- 58 | drawings: 59 | presenterOnly: true 60 | --- 61 | ``` 62 | 63 | ## 绘图同步 64 | 65 | 默认情况下,Slidev 会在所有实例中同步你的绘图。如果你在和他人共享幻灯片,你可能会需要通过以下方式禁用同步: 66 | 67 | ```md 68 | --- 69 | drawings: 70 | syncAll: false 71 | --- 72 | ``` 73 | 74 | 通过这个配置,只有来自演讲者实例的绘图会和其他实例同步。 -------------------------------------------------------------------------------- /.vitepress/theme/components/SlideContainer.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 38 | 39 | 48 | -------------------------------------------------------------------------------- /features/remote-access.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - guide/ui 4 | - CLI: builtin/cli 5 | - Cloudflare Quick Tunnels: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/trycloudflare/ 6 | tags: [远程控制, 工具] 7 | description: | 8 | 在 Slidev 的远程访问特性加持下远程访问你的演示。 9 | --- 10 | 11 | # 远程访问 12 | 13 | 你可以使用 `--remote` 选项以远程访问的方式运行演示文稿: 14 | 15 | ::: code-group 16 | 17 | ```bash [npm] 18 | npm run dev -- --remote 19 | # 等同于 slidev --remote 20 | ``` 21 | 22 | ```bash [pnpm] 23 | pnpm dev -- --remote 24 | # 等同于 slidev --remote 25 | ``` 26 | 27 | ```bash [yarn] 28 | yarn dev --remote 29 | # 等同于 slidev --remote 30 | ``` 31 | 32 | ::: 33 | 34 | ## 密码保护 35 | 36 | 如果你想分享幻灯片,但不想让其他人访问演示者模式,你可以向该选项传递密码,即`--remote=your_password`。然后,访问演示者模式时需要密码。 37 | 38 | 39 | ## 远程隧道 40 | 41 | 你可以开启一个 [Cloudflare Quick Tunnels](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/trycloudflare/) 将你的本地服务器开放到公网(内网穿透)。这样,你就可以在不搭建服务端的情况下与他人共享幻灯片。 42 | 43 | ::: code-group 44 | 45 | ```bash [npm] 46 | npm run dev -- --remote --tunnel 47 | # 等同于 slidev --remote --tunnel 48 | ``` 49 | 50 | ```bash [pnpm] 51 | pnpm dev -- --remote --tunnel 52 | # 等同于 slidev --remote --tunnel 53 | ``` 54 | 55 | ```bash [yarn] 56 | yarn dev --remote --tunnel 57 | # 等同于 slidev --remote --tunnel 58 | ``` 59 | 60 | ::: 61 | -------------------------------------------------------------------------------- /.vitepress/customizations.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | text: '自定义', 4 | link: '/custom/', 5 | }, 6 | { 7 | text: '目录结构', 8 | link: '/custom/directory-structure', 9 | }, 10 | { 11 | text: '代码高亮', 12 | link: '/custom/config-highlighter', 13 | }, 14 | { 15 | text: '配置 Vite 和插件', 16 | link: '/custom/config-vite', 17 | }, 18 | { 19 | text: '配置 Vue 实例', 20 | link: '/custom/config-vue', 21 | }, 22 | { 23 | text: '配置 UnoCSS', 24 | link: '/custom/config-unocss', 25 | }, 26 | { 27 | text: '配置代码运行器', 28 | link: '/custom/config-code-runners', 29 | }, 30 | { 31 | text: '配置自定义语法', 32 | link: '/custom/config-transformers', 33 | }, 34 | { 35 | text: '配置 Monaco', 36 | link: '/custom/config-monaco', 37 | }, 38 | { 39 | text: '配置 KaTeX', 40 | link: '/custom/config-katex', 41 | }, 42 | { 43 | text: '配置 Mermaid', 44 | link: '/custom/config-mermaid', 45 | }, 46 | { 47 | text: '配置路由', 48 | link: '/custom/config-routes', 49 | }, 50 | { 51 | text: '配置快捷键', 52 | link: '/custom/config-shortcuts', 53 | }, 54 | { 55 | text: '配置右键菜单', 56 | link: '/custom/config-context-menu', 57 | }, 58 | { 59 | text: '配置字体', 60 | link: '/custom/config-fonts', 61 | }, 62 | { 63 | text: '配置预处理器', 64 | link: '/custom/config-parser', 65 | }, 66 | ] 67 | -------------------------------------------------------------------------------- /.vitepress/theme/components/FeaturesOverview.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 27 | 28 | 49 | -------------------------------------------------------------------------------- /custom/config-unocss.md: -------------------------------------------------------------------------------- 1 | # 配置 UnoCSS 2 | 3 | 4 | 5 | 从 v0.42.0 开始,[UnoCSS](https://unocss.dev) 是 Slidev 的默认 CSS 框架。UnoCSS是一个快速的原子CSS引擎,具有完全的灵活性和可扩展性,并且对大多数 Tailwind CSS 类都有**开箱即用**的支持,你也可以使用自己的配置对其进行扩展。 6 | 7 | 默认地,Slidev 开箱即用地使用了以下的预设: 8 | 9 | - [@unocss/preset-uno](https://unocss.dev/presets/uno) - Tailwind / Windi CSS 兼容工具 10 | - [@unocss/preset-attributify](https://unocss.dev/presets/attributify) - Attributify 模式 11 | - [@unocss/preset-icons](https://unocss.dev/presets/icons) - 以 class 方式使用任何 icon 12 | - [@unocss/preset-web-fonts](https://unocss.dev/presets/web-fonts) - 轻松使用网络字体文件 13 | - [@unocss/transformer-directives](https://unocss.dev/transformers/directives) - 在 CSS 中使用 `@apply` 14 | 15 | Slidev 也添加了一些 shortcuts ,可以参考 [源代码](https://github.com/slidevjs/slidev/blob/main/packages/client/uno.config.ts). 16 | 17 | 因此,你可以按照自己想要的方式写 style。例如: 18 | 19 | ```html 20 |
21 | 22 | ### Name 23 | 24 | - Item 1 25 | - Item 2 26 | 27 |
28 | ``` 29 | 30 | ## 配置项 31 | 32 | 你可以在项目的根文件夹中创建 `uno.config.ts`来扩展内置配置项 33 | 34 | ```ts twoslash 35 | import { defineConfig } from 'unocss' 36 | 37 | export default defineConfig({ 38 | shortcuts: { 39 | // 自定义默认的背景 40 | 'bg-main': 'bg-white text-[#181818] dark:(bg-[#121212] text-[#ddd])', 41 | }, 42 | // ... 43 | }) 44 | ``` 45 | 46 | 参见 [UnoCSS 配置文件](https://unocss.dev/guide/config-file) 以了解更多。 47 | -------------------------------------------------------------------------------- /.vitepress/theme/components/LinkInline.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 47 | -------------------------------------------------------------------------------- /.vitepress/theme/components/FeaturesAnimationInner.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 39 | -------------------------------------------------------------------------------- /features/shiki-magic-move.md: -------------------------------------------------------------------------------- 1 | --- 2 | depends: 3 | - guide/syntax#code-block 4 | - guide/animations 5 | relates: 6 | - Shiki Magic Move: https://github.com/shikijs/shiki-magic-move 7 | since: v0.48.0 8 | tags: [代码块, 动画] 9 | description: | 10 | 控制代码变化时的细粒度过渡,类似于 Keynote 中的 Magic Move 效果。 11 | --- 12 | 13 | # Shiki Magic Move 14 | 15 | [Shiki Magic Move](https://github.com/shikijs/shiki-magic-move) 让你能够控制代码变化时的细粒度过渡,类似于 Keynote 中的 Magic Move 效果。在 [此处](https://shiki-magic-move.netlify.app/) 查看它是如何工作的。 16 | 17 | 18 | 19 | 在 Slidev 中,我们将 Magic Move 绑定到 [点击事件](/guide/animations#click-animation) 中。它的语法是用````md magic-move 包裹代表每个步骤的代码块(注意是**四个反引号**)。这将被转换为一个根据动画步骤变化的代码快。 20 | 21 | `````md 22 | ````md magic-move 23 | ```js 24 | console.log(`Step ${1}`) 25 | ``` 26 | ```js 27 | console.log(`Step ${1 + 1}`) 28 | ``` 29 | ```ts 30 | console.log(`Step ${3}` as string) 31 | ``` 32 | ```` 33 | ````` 34 | 35 | 也可以将 Magic Move 和 混合使用,例如: 36 | 37 | `````md 38 | ````md magic-move {at:4, lines: true} // [!code hl] 39 | ```js {*|1|2-5} // [!code hl] 40 | let count = 1 41 | function add() { 42 | count++ 43 | } 44 | ``` 45 | 46 | 在代码块之间的内容会被忽略,可以作为注释。 47 | 48 | ```js {*}{lines: false} // [!code hl] 49 | let count = 1 50 | const add = () => count += 1 51 | ``` 52 | ```` 53 | ````` 54 | -------------------------------------------------------------------------------- /.vitepress/theme/components/AddonInfo.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 51 | -------------------------------------------------------------------------------- /guide/theme-addon.md: -------------------------------------------------------------------------------- 1 | # 主题和插件 2 | 3 | 一个幻灯片项目可以有一个主题和多个插件。它们可以为你的幻灯片项目提供样式、组件、布局和其他配置。 4 | 5 | ## 使用主题 {#use-theme} 6 | 7 | 在 Slidev 中更换主题非常简单。你只需要在 [headmatter](../custom/index#headmatter) 中添加 `theme` 选项: 8 | 9 | ```md 10 | --- 11 | theme: seriph 12 | --- 13 | 14 | # The first slide 15 | ``` 16 | 17 | 你可以在 [主题合集](../resources/theme-gallery) 中找到官方主题和社区主题。 18 | 19 | ::: info 主题名称的规范 20 | 21 | - 你可以使用相对或绝对路径指定本地主题文件夹,例如 `../my-theme` 22 | - 你也可以直接使用完整的包名作为主题名称 23 | - 如果主题是[官方主题](../resources/theme-gallery#official-themes)或者命名为 `slidev-theme-name`,你可以省略 `slidev-theme-` 前缀 24 | - 对于作用域包,如 `@org/slidev-theme-name`,需要使用完整的包名 25 | 26 | ::: 27 | 28 | 启动服务器后,你将会看到如下提示,选择同意即可安装该主题: 29 | 30 |
31 |
32 | ? The theme "@slidev/theme-seriph" was not found in your project, do you want to install it now? › (Y/n)
33 | 
34 |
35 | 36 | 或者,你也可以手动安装主题: 37 | 38 | ```bash 39 | $ npm install @slidev/theme-seriph 40 | ``` 41 | 42 | 这就是使用主题的全部步骤!如果你想要更多关于主题的细节,可以查看主题的 README。 43 | 44 | 47 | 48 | ## 使用插件 {#use-addon} 49 | 50 | 插件和主题类似,但更加灵活,可以用来为你的幻灯片项目添加额外的功能。你可以为你的项目添加多个插件,它们可以用来添加额外的功能。 51 | 52 | 要使用插件,你可以在 [headmatter](../custom/index#headmatter) 中添加 `addons` 选项: 53 | 54 | ```md 55 | --- 56 | addons: 57 | - excalidraw 58 | - '@slidev/plugin-notes' 59 | --- 60 | ``` 61 | 62 | 你可以在 [插件合集](../resources/addon-gallery) 中找到官方插件和社区插件。 63 | -------------------------------------------------------------------------------- /features/draggable.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: [布局] 3 | description: | 4 | 可以用鼠标拖动来移动、旋转和调整大小的元素。 5 | --- 6 | 7 | # 可拖拽元素 8 | 9 | 可拖动元素使你能够通过鼠标拖动来移动、调整大小和旋转元素。这对于在幻灯片中创建浮动元素非常有用。 10 | 11 | ## 指令式用法 12 | 13 | ### 在 frontmatter 中设定 14 | 15 | ```md 16 | --- 17 | dragPos: 18 | square: Left,Top,Width,Height,Rotate 19 | --- 20 | 21 | 22 | ``` 23 | 24 | ### 在指令值中设定 25 | 26 | ::: warning 27 | Slidev 使用正则表达式来更新幻灯片内容中的位置值。如果你遇到问题,请使用 frontmatter 来定义值。 28 | ::: 29 | 30 | ```md 31 | 32 | ``` 33 | 34 | ## 组件式用法 35 | 36 | ### 在 frontmatter 中设定 37 | 38 | ```md 39 | --- 40 | dragPos: 41 | foo: Left,Top,Width,Height,Rotate 42 | --- 43 | 44 | 45 | 46 | 使用`v-drag`组件来创建一个可拖动的容器! 47 | 48 | ``` 49 | 50 | ### 通过 props 设定 51 | 52 | ```md 53 | 54 | 55 | 使用`v-drag`组件来创建一个可拖动的容器! 56 | 57 | ``` 58 | 59 | ## 创建一个可拖拽元素 60 | 61 | 创建新的可拖动元素时,不需要指定位置值(但如果要将位置存储在 frontmatter,则需要指定位置名称)。Slidev 将帮你自动生成初始位置值。 62 | 63 | ## 自动调整高度 64 | 65 | 你可以将 `Height` 设置为 `NaN`(in)或 `_`(如果使用组件),使可拖动元素的高度根据它的内容自动调整。 66 | 67 | 68 | ## 控制 69 | 70 | - 双击可拖动元素以开始拖动。 71 | - 你还可以使用箭头键移动元素。 72 | - 拖动时按住 `Shift` 键以保持其纵横比。 73 | - 单击可拖动元素以外区域以停止拖动。 74 | 75 | ## 可拖动剪头 76 | 77 | `` 组件创建了一个可拖动的箭头元素。使用它只需要这样做: 78 | 79 | ```md 80 | 81 | ``` 82 | 83 | 你会得到一个可拖动的箭头元素。其他 props 与 [`Arrow` 组件](/builtin/components#Arrow)相同。 84 | 85 | -------------------------------------------------------------------------------- /.vitepress/utils.ts: -------------------------------------------------------------------------------- 1 | import { data as features } from '../features/index.data.js' 2 | import { Advanced, Guides } from './pages' 3 | 4 | function removeHash(link: string) { 5 | const idx = link.lastIndexOf('#') 6 | return idx < 0 ? link : link.slice(0, idx) 7 | } 8 | 9 | function getGuideTitle(id: string) { 10 | return Guides.find(g => g.link.endsWith(`/${id}`))?.text ?? Advanced.find(g => g.link.endsWith(id))?.text ?? id 11 | } 12 | 13 | export function resolveLink(link: string): { 14 | kind: 'external' | 'features' | 'guide' 15 | url: string 16 | title?: string 17 | tags?: string[] 18 | descripton?: string 19 | } { 20 | const [kind, nameWithHash] = link.split('/') 21 | const name = removeHash(nameWithHash) 22 | switch (kind) { 23 | case 'http:': 24 | case 'https:': 25 | case 'mailto:': 26 | return { kind: 'external', url: link } 27 | case 'features': { 28 | const feature = features[name] 29 | if (!feature) 30 | throw new Error(`Feature "${name}" not found.`) 31 | return { 32 | kind: 'features', 33 | title: `✨ ${feature.title}`, 34 | tags: feature.tags, 35 | descripton: feature.description, 36 | url: `/features/${nameWithHash}`, 37 | } 38 | } 39 | case 'guide': { 40 | return { 41 | kind: 'guide', 42 | title: `📖 ${getGuideTitle(name)}`, 43 | tags: ['指南'], 44 | descripton: '点击阅读该指南', 45 | url: `/guide/${nameWithHash}`, 46 | } 47 | } 48 | default: 49 | throw new Error(`Invalid link: ${link}`) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /.vitepress/theme/components/LinkCard.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 32 | 33 | 62 | -------------------------------------------------------------------------------- /features/latex.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - Demo: /demo/starter/11 4 | - KaTeX: https://katex.org/ 5 | tags: [代码块, 语法] 6 | description: | 7 | 在 KaTex 驱动下,Slidev 开箱即用地支持 LaTex。 8 | --- 9 | 10 | # LaTeX 11 | 12 | Slidev 开箱即用地支持 LaTeX,基于 [KaTeX](https://katex.org/)。 13 | 14 | ## 行内公式 {#inline} 15 | 16 | 在 LaTeX 公式左右各加一个 `$`,以渲染行内公式。 17 | 18 | ```md 19 | $\sqrt{3x-1}+(1+x)^2$ 20 | ``` 21 | 22 | ## 块级公式 {#block} 23 | 24 | 当使用两个 (`$$`) 时,会进行块级渲染。这种模式会使用更大的符号,并将结果居中。 25 | 26 | ```latex 27 | $$ 28 | \begin{aligned} 29 | \nabla \cdot \vec{E} &= \frac{\rho}{\varepsilon_0} \\ 30 | \nabla \cdot \vec{B} &= 0 \\ 31 | \nabla \times \vec{E} &= -\frac{\partial\vec{B}}{\partial t} \\ 32 | \nabla \times \vec{B} &= \mu_0\vec{J} + \mu_0\varepsilon_0\frac{\partial\vec{E}}{\partial t} 33 | \end{aligned} 34 | $$ 35 | ``` 36 | 37 | ## 逐行高亮 38 | 39 | 要想高亮特定行,只需在括号 `{}` 中添加行号即可。行号默认从 1 开始。 40 | 41 | ```latex 42 | $$ {1|3|all} 43 | \begin{aligned} 44 | \nabla \cdot \vec{E} &= \frac{\rho}{\varepsilon_0} \\ 45 | \nabla \cdot \vec{B} &= 0 \\ 46 | \nabla \times \vec{E} &= -\frac{\partial\vec{B}}{\partial t} \\ 47 | \nabla \times \vec{B} &= \mu_0\vec{J} + \mu_0\varepsilon_0\frac{\partial\vec{E}}{\partial t} 48 | \end{aligned} 49 | $$ 50 | ``` 51 | 52 | LaTeX 块也可以使用 [代码块](#line-highlighting) 的 `at` 和 `finally` 选项。 53 | 54 | ## 化学方程式 55 | 56 | 为了能够呈现化学方程式,需要加载 KaTeX 的扩展 [mhchem](https://github.com/KaTeX/KaTeX/tree/main/contrib/mhchem)。 57 | 58 | 创建包含以下内容的 `vite.config.ts` : 59 | 60 | ```ts 61 | import 'katex/contrib/mhchem' 62 | 63 | export default {} 64 | ``` 65 | 66 | 现在化学方程式可以被正常渲染了。 67 | 68 | ```latex 69 | $$ 70 | \displaystyle{\ce{B(OH)3 + H2O <--> B(OH)4^- + H+}} 71 | $$ 72 | ``` 73 | 74 | 了解更多: [mhchem 语法](https://mhchem.github.io/MathJax-mhchem) 75 | 76 | --- 77 | 78 | 79 | -------------------------------------------------------------------------------- /.vitepress/theme/components/TheTweet.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 60 | 61 | 72 | -------------------------------------------------------------------------------- /features/icons.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - Iconify: https://iconify.design/ 4 | - Icones: https://icones.js.org/ 5 | - unplugin-icons: https://github.com/antfu/unplugin-icons 6 | tags: [components] 7 | description: | 8 | 直接在 markdown 中使用几乎所有开源图标集中的图标。 9 | --- 10 | 11 | # 图标 12 | 13 | Slidev 让你能在安装相应的包后,**直接**在 markdown 中访问几乎所有开源图标集。 14 | 15 | 由 [`unplugin-icons`](https://github.com/antfu/unplugin-icons) 及 [Iconify](https://iconify.design/) 驱动。 16 | 17 | 命名遵循 [Iconify](https://iconify.design/) 的约定 `{图标集名}-{图标名}`,例如: 18 | 19 | - `` - 出自 [Material Design Icons](https://github.com/Templarian/MaterialDesign) - [`@iconify-json/mdi`](https://npmjs.com/package/@iconify-json/mdi) 20 | - `` - 出自 [Carbon](https://github.com/carbon-design-system/carbon/tree/main/packages/icons) - [`@iconify-json/carbon`](https://npmjs.com/package/@iconify-json/carbon) 21 | - `` - 出自 [Unicons Monochrome](https://github.com/Iconscout/unicons) - [`@iconify-json/uim`](https://npmjs.com/package/@iconify-json/uim) 22 | - `` - from [Twemoji](https://github.com/twitter/twemoji) - [`@iconify-json/twemoji`](https://npmjs.com/package/@iconify-json/twemoji) 23 | - `` - 出自 [SVG Logos](https://github.com/gilbarbara/logos) - [`@iconify-json/logos`](https://npmjs.com/package/@iconify-json/logos) 24 | - 等等...... 25 | 26 | 你可以在 [Icônes](https://icones.js.org/) 预览和搜索所有的图标 27 | 28 | ### 为图标添加样式 29 | 30 | 你可以像其他 HTML 元素一样为图标添加样式,例如: 31 | 32 | ```html 33 | 34 | 35 | 36 | ``` 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /features/index.data.ts: -------------------------------------------------------------------------------- 1 | import { basename } from 'node:path' 2 | import { createContentLoader } from 'vitepress' 3 | 4 | export interface Feature { 5 | name: string 6 | title: string 7 | link: string 8 | description: string 9 | depends: string[] 10 | relates: string[] 11 | derives: string[] 12 | tags: string[] 13 | since?: string 14 | } 15 | 16 | export default createContentLoader('features/*.md', { 17 | includeSrc: true, 18 | transform(data) { 19 | const derivesMap: Record = {} 20 | for (const md of data) { 21 | const name = basename(md.url, '.md') 22 | if (name === 'index' || name === 'features') 23 | continue 24 | for (const depend of md.frontmatter.depends ?? []) { 25 | const dependName = depend.match(/\/([\w-]+)($|#)/)?.[1] 26 | if (dependName) { 27 | derivesMap[dependName] ??= [] 28 | derivesMap[dependName].push(`features/${name}`) 29 | } 30 | } 31 | } 32 | 33 | const result: Record = {} 34 | for (const md of data) { 35 | const name = basename(md.url, '.md') 36 | if (name === 'index' || name === 'features') 37 | continue 38 | const title = md.src?.match(/^# (.*)$/m)?.[1]?.trim() ?? name 39 | const derives = md.frontmatter.derives ?? [] 40 | for (const d of derivesMap[name] ?? []) { 41 | if (!derives.includes(d)) { 42 | derives.push(d) 43 | } 44 | } 45 | result[name] = { 46 | name, 47 | title, 48 | link: `/features/${name}.html`, 49 | description: md.frontmatter.description ?? '', 50 | depends: md.frontmatter.depends ?? [], 51 | relates: md.frontmatter.relates ?? [], 52 | derives, 53 | tags: md.frontmatter.tags ?? [], 54 | since: md.frontmatter.since, 55 | } 56 | } 57 | return result 58 | }, 59 | }) 60 | 61 | export declare const data: Record 62 | -------------------------------------------------------------------------------- /public/assets/arrow-bottom-left.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 6 | 9 | 10 | 12 | 15 | 16 | 18 | 21 | 22 | 23 | 24 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.vitepress/theme/components/Layout.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 55 | -------------------------------------------------------------------------------- /custom/config-vite.md: -------------------------------------------------------------------------------- 1 | # 配置 Vite 及其扩展 2 | 3 | 4 | 5 | Slidev 基于 [Vite](http://vitejs.dev/) 实现。这意味着你可以利用 Vite 强大的插件系统来进一步定制你的幻灯片。 6 | 7 | 如果项目中存在 `vite.config.ts` 文件,将被自动读取,并将与 Slidev,你的主题和扩展插件提供的配置文件合并 8 | 9 | ## 配置内部插件 10 | 11 | Slidev 已经内置了以下插件: 12 | 13 | - [@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue) 14 | - [unplugin-vue-components](https://github.com/unplugin/unplugin-vue-components) 15 | - [unplugin-icons](https://github.com/unplugin/unplugin-icons) 16 | - [vite-plugin-vue-markdown](https://github.com/unplugin/unplugin-vue-markdown) 17 | - [vite-plugin-remote-assets](https://github.com/antfu/vite-plugin-remote-assets) 18 | - [unocss/vite](https://github.com/unocss/unocss/tree/main/packages/vite) 19 | 20 | 如需对内置插件列表进行配置,先创建 `vite.config.ts`,其内容如下。请注意,Slidev 对这些插件有些[预设配置](https://github.com/slidevjs/slidev/blob/main/packages/slidev/node/vite/index.ts),如下做法会覆盖其中一些配置,可能会导致应用崩溃。请将此功能视为**高级功能**,在继续操作前,请确保了解配置的作用。 21 | 22 | 23 | 24 | ```ts twoslash 25 | /// 26 | import type MarkdownIt from 'markdown-it' 27 | declare const MyPlugin: (md: any) => void 28 | // ---cut--- 29 | import { defineConfig } from 'vite' 30 | 31 | export default defineConfig({ 32 | slidev: { 33 | vue: { 34 | /* vue 的选项 */ 35 | }, 36 | markdown: { 37 | /* markdown-it 的选项 */ 38 | markdownItSetup(md) { 39 | /* 自定义的 markdown-it 插件 */ 40 | md.use(MyPlugin, /* ... */) 41 | }, 42 | }, 43 | /* 其他插件的选项 */ 44 | }, 45 | }) 46 | ``` 47 | 48 | 了解更多:[类型定义](https://github.com/slidevjs/slidev/blob/main/packages/types/src/vite.ts#L11) 49 | 50 | ::: warning 51 | 52 | Slidev 中不可以重新添加已内置使用的插件。例如,以下配置将会导致错误: 53 | 54 | ```ts twoslash 55 | import { defineConfig } from 'vite' 56 | import Vue from '@vitejs/plugin-vue' 57 | 58 | export default defineConfig({ 59 | plugins: [ 60 | Vue({ 61 | /* vue 的选项 */ 62 | }) 63 | ], 64 | }) 65 | ``` 66 | 67 | 请将Vue选项传递给 `slidev.vue` 字段,如上文所述。 68 | 69 | ::: 70 | -------------------------------------------------------------------------------- /custom/config-highlighter.md: -------------------------------------------------------------------------------- 1 | # 配置语法高亮 2 | 3 | Slidev 使用 [Shiki](https://github.com/shikijs/shiki) ,一个基于 TextMate 语法,与 VS Code 一样准确的代码高亮器。它直接生成带样式的 HTML 元素,所以不需要引入额外的 CSS 文件。Shiki 自带了一系列 [内置主题](https://shiki.style/themes)。而在 Slidev 中,我们还提供内置的 [TwoSlash](#twoslash-integration) 功能。 4 | 5 | ## 配置 Shiki {#configure-shiki} 6 | 7 | 8 | 9 | 创建包含以下内容的 `./setup/shiki.ts` 文件: 10 | 11 | ```ts twoslash 12 | /* ./setup/shiki.ts */ 13 | import { defineShikiSetup } from '@slidev/types' 14 | 15 | export default defineShikiSetup(() => { 16 | return { 17 | themes: { 18 | dark: 'min-dark', 19 | light: 'min-light', 20 | }, 21 | transformers: [ 22 | // ... 23 | ], 24 | } 25 | }) 26 | ``` 27 | 28 | 如果你想添加自定义主题或语言( JSON 中的 TextMate 语法/主题),你可以在上述文件中导入它们: 29 | 30 | 31 | 32 | ```ts twoslash 33 | /* ./setup/shiki.ts */ 34 | import { defineShikiSetup } from '@slidev/types' 35 | // ---cut-start--- 36 | // @ts-expect-error missing types 37 | // ---cut-end--- 38 | import customTheme from './customTheme.tmTheme.json' 39 | // ---cut-start--- 40 | // @ts-expect-error missing types 41 | // ---cut-end--- 42 | import customLanguage from './customLanguage.tmLanguage.json' 43 | 44 | export default defineShikiSetup(() => { 45 | return { 46 | themes: { 47 | dark: customTheme, 48 | light: 'min-light', 49 | }, 50 | langs: [ 51 | 'js', 52 | 'typescript', 53 | 'cpp', 54 | customLanguage, 55 | // ... 56 | ], 57 | transformers: [ 58 | // ... 59 | ], 60 | } 61 | }) 62 | ``` 63 | 64 | 更多详情请参考 [Built-in languages](https://shiki.style/languages) 及 [Built-in themes](https://shiki.style/themes) 以及 Shiki 的 [官方文档](https://shiki.style) 。 65 | 66 | :::info 67 | 目前,Shiki 中的 Magic Move 还不支持页面切换效果。 68 | ::: 69 | 70 | ## 配置 Prism 71 | 72 | :::warning 73 | Prism 已被 Slidev 停止支持,并且将在未来版本中被移除。请考虑更换到 Shiki 74 | ::: 75 | 76 | 如果要配置 Prism,你可以引入相应的主题 CSS,或者使用 [`prism-theme-vars`](https://github.com/antfu/prism-theme-vars) 来进行亮/暗模式下的主题配置。请参考相应文档以了解更多细节。 77 | -------------------------------------------------------------------------------- /.vitepress/pages.ts: -------------------------------------------------------------------------------- 1 | export const Guides = [ 2 | { 3 | text: '为什么选 Slidev', 4 | link: '/guide/why', 5 | }, 6 | { 7 | text: '快速上手', 8 | link: '/guide/', 9 | }, 10 | { 11 | text: '语法', 12 | link: '/guide/syntax', 13 | }, 14 | { 15 | text: '用户界面', 16 | link: '/guide/ui', 17 | }, 18 | { 19 | text: '动画', 20 | link: '/guide/animations', 21 | }, 22 | { 23 | text: '主题和插件', 24 | link: '/guide/theme-addon', 25 | }, 26 | { 27 | text: '组件', 28 | link: '/guide/component', 29 | }, 30 | { 31 | text: '布局', 32 | link: '/guide/layout', 33 | }, 34 | { 35 | text: '导出', 36 | link: '/guide/exporting', 37 | }, 38 | { 39 | text: '部署', 40 | link: '/guide/hosting', 41 | }, 42 | { 43 | text: '常见问答', 44 | link: '/guide/faq', 45 | }, 46 | ] 47 | 48 | export const BuiltIn = [ 49 | { 50 | text: '命令行工具', 51 | link: '/builtin/cli', 52 | }, 53 | { 54 | text: '内置组件', 55 | link: '/builtin/components', 56 | }, 57 | { 58 | text: '内置布局', 59 | link: '/builtin/layouts', 60 | }, 61 | ] 62 | 63 | export const Advanced = [ 64 | { 65 | text: '全局上下文', 66 | link: '/guide/global-context', 67 | }, 68 | { 69 | text: '编写布局', 70 | link: '/guide/write-layout', 71 | }, 72 | { 73 | text: '编写主题', 74 | link: '/guide/write-theme', 75 | }, 76 | { 77 | text: '编写插件', 78 | link: '/guide/write-addon', 79 | }, 80 | ] 81 | 82 | export const Resources = [ 83 | { 84 | text: '案例展示', 85 | link: '/resources/showcases', 86 | }, 87 | { 88 | text: '主题合集', 89 | link: '/resources/theme-gallery', 90 | }, 91 | { 92 | text: '插件合集', 93 | link: '/resources/addon-gallery', 94 | }, 95 | { 96 | text: '学习资源', 97 | link: '/resources/learning', 98 | }, 99 | { 100 | text: '精选封面', 101 | link: '/resources/covers', 102 | }, 103 | { 104 | text: '更新日志', 105 | link: 'https://github.com/slidevjs/slidev/releases', 106 | }, 107 | ] 108 | -------------------------------------------------------------------------------- /.vitepress/theme/components/ShowCaseInfo.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 66 | -------------------------------------------------------------------------------- /custom/config-code-runners.md: -------------------------------------------------------------------------------- 1 | # 配置代码运行器 2 | 3 | 4 | 5 | 在 Monaco 代码运行器中运行自定义语言。 6 | 7 | Slidev 内置了对 JavaScript 与 TypeScript 运行器。 它们能直接在浏览器中运行,但 **没有** 沙盒环境的保护。 如果你想要更高级的集成, 你可以提供自己的代码运行器,将代码发送到远程服务器、在 Web Worker 中运行,或者以你希望的任何方式运行。 8 | 9 | 你需要创建含以下内容的 `./setup/code-runners.ts` 文件: 10 | 11 | 12 | 13 | ```ts twoslash 14 | declare const executePythonCodeRemotely: (code: string) => Promise 15 | declare const sanitizeHtml: (html: string) => string 16 | // ---cut--- 17 | import { defineCodeRunnersSetup } from '@slidev/types' 18 | 19 | export default defineCodeRunnersSetup(() => { 20 | return { 21 | async python(code, ctx) { 22 | // 以某种方式执行代码并获取输出 23 | const result = await executePythonCodeRemotely(code) 24 | return { 25 | text: result 26 | } 27 | }, 28 | html(code, ctx) { 29 | return { 30 | html: sanitizeHtml(code) 31 | } 32 | }, 33 | // 也可以添加其他语言。键是语言id,值是运行器函数 34 | } 35 | }) 36 | ``` 37 | 38 | ## 运行上下文 39 | 40 | 第二个传入参数 `ctx` 是运行的上下文, 包含了以下属性: 41 | 42 | ```ts twoslash 43 | import type { CodeRunnerOutputs } from '@slidev/types' 44 | import type { CodeToHastOptions } from 'shiki' 45 | // ---cut--- 46 | export interface CodeRunnerContext { 47 | /** 48 | * 通过 `runnerOptions` 属性传递给运行器的选项。 49 | */ 50 | options: Record 51 | /** 52 | * 使用 Shiki 高亮代码。 53 | */ 54 | highlight: (code: string, lang: string, options?: Partial) => string 55 | /** 56 | * 使用其他代码运行器运行代码。 57 | */ 58 | run: (code: string, lang: string) => Promise 59 | } 60 | ``` 61 | 62 | ## 运行器输出 63 | 64 | 运行器可以返回文本或 HTML 输出,或者一个要挂载的 HTML 元素。更多详情请参考 [code-runner.ts](https://github.com/slidevjs/slidev/blob/main/packages/types/src/code-runner.ts) 的类型定义。 65 | 66 | ## 附加运行依赖 67 | 68 | 默认地,Slidev 将扫描 Markdown 源文件并自动为运行器导入必要的 JavaScript 依赖项。如果你希望手动指定依赖,你可以在 slide 的 frontmatter 中使用 `monacoRunAdditionalDeps` 选项: 69 | 70 | ```yaml 71 | monacoRunAdditionalDeps: 72 | - ./path/to/dependency 73 | - lodash-es 74 | ``` 75 | 76 | ::: tip 77 | 这些路径是相对于 `snippets` 目录解析的。并且依赖项的名称应该与代码中导入的名称完全相同。 78 | ::: 79 | -------------------------------------------------------------------------------- /guide/write-theme.md: -------------------------------------------------------------------------------- 1 | # 编写主题 2 | 3 | > 请先阅读 。 4 | 5 | 每个幻灯片项目只能有一个主题。主题应专注于提供幻灯片的外观。如果功能与外观无关且可以单独使用,则应将其实现为 [插件](./write-addon)。 6 | 7 | 我们建议您使用我们的生成器来搭建您的第一个主题: 8 | 9 | ::: code-group 10 | 11 | ```bash [npm] 12 | $ npm init slidev-theme@latest 13 | ``` 14 | 15 | ```bash [pnpm] 16 | $ pnpm init slidev-theme 17 | ``` 18 | 19 | ```bash [yarn] 20 | $ yarn create slidev-theme 21 | ``` 22 | 23 | ::: 24 | 25 | 你也可以参考[官方主题](../resources/theme-gallery#official-themes)作为示例。 26 | 27 | ## 主题能力 {#capability} 28 | 29 | 一个主题可以实现以下功能: 30 | 31 | - 全局样式 32 | - 提供默认配置 33 | - 提供自定义布局或覆盖现有布局 34 | - 提供自定义组件 35 | - 配置 UnoCSS、Shiki 等工具 36 | 37 | 但是,不建议在主题中实现以下功能,这些功能可能更适合 [实现为插件](./write-addon): 38 | 39 | - 新的代码片段 40 | - 新的代码运行器 41 | - 其他可以单独使用的功能 42 | 43 | 基本上,提供全局样式、布局、组件和配置工具的方式与在幻灯片项目中提供这些的方式相同。例如,要配置 Shiki,您可以创建一个 `./setup/shiki.ts`,如[配置高亮](../custom/config-highlighter)中所述。您可以参考[自定义指南](/custom/)获取更多信息。 44 | 45 | 若要提供默认的 Slidev 配置,您可以在 `package.json` 文件中添加一个 `slidev.defaults` 字段,它将与用户的配置合并: 46 | 47 | ```json 48 | { 49 | "slidev": { 50 | "defaults": { 51 | "transition": "slide-left", 52 | "aspectRatio": "4/3" 53 | } 54 | } 55 | } 56 | ``` 57 | 58 | ### 限制 Slidev 版本 {#restrict-version} 59 | 60 | 若该主题依赖于 Slidev 的某个新功能,您可以设置主题所需的最低 Slidev 版本: 61 | 62 | ```json 63 | { 64 | "engines": { 65 | "slidev": ">=0.48.0" 66 | } 67 | } 68 | ``` 69 | 70 | 当使用不兼容的版本时,将显示错误消息。 71 | 72 | ### 元信息 {#metadata} 73 | 74 | Slidev 默认主题支持浅色模式和深色模式。如果您只希望您的主题在特定颜色模式下呈现,您需要在 `package.json` 中显式指定: 75 | 76 | ```json 77 | { 78 | "slidev": { 79 | "colorSchema": "light" // or "dark" or "both" 80 | } 81 | } 82 | ``` 83 | 84 | ## 预览主题 {#previewing} 85 | 86 | 你可以通过一个示例幻灯片来预览主题。为此,请创建一个 `./slides.md` 文件,并在其中添加以下 headmatter 配置: 87 | 88 | ```md 89 | --- 90 | theme: ./ # 使用当前目录的作为主题 91 | --- 92 | ``` 93 | 94 | 其他使用方式与普通的幻灯片相同。 95 | 96 | ## 发布主题 {#publishing} 97 | 98 | 当发布主题时,非 JS 文件(如 `.vue` 和 `.ts` 文件)可以直接发布而无需编译。Slidev 在使用主题时会自动编译它们。 99 | 100 | 主题应遵循以下约定: 101 | 102 | - 包名应以 `slidev-theme-` 开头。例如,`slidev-theme-name` 或 `@scope/slidev-theme-name` 103 | - 在 `package.json` 的 `keywords` 字段中添加 `"slidev-theme"` 和 `"slidev"` 104 | 105 | 主题可以在本地使用而无需发布到 NPM。如果您的主题仅供个人使用,您可以将其简单地用作本地主题,或者将其发布为私有作用域包。但是,如果您想与他人分享,建议将其发布到 NPM。 106 | -------------------------------------------------------------------------------- /features/global-layers.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: [导航, 布局] 3 | description: | 4 | 为所有幻灯片创建图层。 5 | --- 6 | 7 | # 全局图层 8 | 9 | 全局图层允许你拥有**持续存在**的跨幻灯片自定义组件。这对于有页脚、跨幻灯片动画、全局特效等来说可能很有用。 10 | 11 | Slidev 为这种用法提供了三种图层,在你的项目根目录下创建 `global-top.vue` 、 `global-bottom.vue` 或 `custom-nav-controls.vue` 文件,它们会被自动识别。 12 | 13 | **每张**幻灯片也有图层:`layouts/slide-top.vue`和`layout/slide-bottom.vue`。其用法类似于全局图层,但它们应用于每张幻灯片,因此可能有多个实例。 14 | 15 | 16 | ::: tip 17 | 导出时,应使用 `--per-slide` 选项以确保全局层正确应用于每张幻灯片。 18 | ::: 19 | 20 | ## 图层关系 21 | 22 | 在 z 轴上,从上到下排序: 23 | 24 | - 导航栏 25 | - 自定义导航栏控制 (`custom-nav-controls.vue`) 26 | - 全局顶层 (`global-top.vue`) - 单个实例 27 | - 幻灯片顶层 (`slide-top.vue`) - 每页间独立实例 28 | - 幻灯片内容 29 | - 幻灯片底层 (`slide-bottom.vue`) - 每页间独立实例 30 | - 全局底层 (`global-bottom.vue`) - 单个实例 31 | 32 | ## 示例 33 | 34 | ```html 35 | 36 | 39 | ``` 40 | 41 | 文本 `你的名字` 将出现在你的所有幻灯片中。 42 | 43 | ```html 44 | 45 | 50 | ``` 51 | 52 | `Next` 按钮会出现在导航栏中。 53 | 54 | 如需有条件地启用它,你可以用 。 55 | 56 | ```html 57 | 58 | 66 | ``` 67 | 68 | ```html 69 | 70 | 78 | ``` 79 | 80 | ```html 81 | 82 | 90 | ``` 91 | 92 | ```html 93 | 94 | 95 | 100 | ``` 101 | -------------------------------------------------------------------------------- /features/vscode-extension.md: -------------------------------------------------------------------------------- 1 | --- 2 | relates: 3 | - VS Code: https://code.visualstudio.com/ 4 | - 在插件市场中查看: https://marketplace.visualstudio.com/items?itemName=antfu.slidev 5 | - 在 OVSX 中查看: https://open-vsx.org/extension/antfu/slidev 6 | tags: [编辑器] 7 | description: | 8 | 帮助你更好的组织你的幻灯片并进行快速浏览。 9 | --- 10 | 11 | # VS Code 拓展 12 | 13 |

14 | 15 | Slidev 16 | 17 |

18 | 19 | 20 | Visual Studio Marketplace Version 21 |   22 | 23 | Visual Studio Marketplace Downloads 24 | 25 | 26 | Slidev 的 VS Code 扩展提供了一些特性来帮助你更好的组织你的幻灯片并进行快速浏览。 27 | 28 | ### 特性 29 | 30 | - 在侧边面板中预览幻灯片 31 | - 幻灯片树形图 32 | - 为幻灯片重新排序 33 | - 幻灯片块的折叠 34 | - 多幻灯片项目支持 35 | - 一键启动开发服务器 36 | 37 | ![](https://github.com/slidevjs/slidev/assets/63178754/2c9ba01a-d21f-4b33-b6b6-4e249873f865) 38 | 39 | 40 | 41 | 42 | 43 | ### 安装 44 | 45 | 你可以从 [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=antfu.slidev) 或者 [Open VSX Registry](https://open-vsx.org/extension/antfu/slidev) 中安装扩展 46 | 47 | ### 用法 48 | 49 | 单击活动栏中的 `Slidev` 图标打开**Slidev面板**。在Slidev面板中,你可以看到项目树形图、幻灯片树形图和预览 webview。 50 | 51 | 在**项目树形图**中,你可以看到工作区中的所有 Slidev 项目。你可以单击该项目以打开相应的文件,然后单击其上的 图标以切换当前项目。 图标允许你加载未自动扫描的幻灯片项目。 52 | 53 | 在**幻灯片树形图**中,你可以看到当前项目中的所有幻灯片。你可以单击该项目将光标移动到编辑器中的幻灯片上,然后拖放以重新排序幻灯片。 54 | 55 | 在**webview预览**中,你可以单击 图标启动开发服务器,然后单击 图标在浏览器中打开幻灯片。切换 图标以将预览导航与编辑器光标同步/取消同步。 56 | 57 | 你还可以使用一些**命令**。在命令面板中键入 `Slidev` 以查看它们。 58 | 59 | 你可以将 glob 模式添加 `slidev.include` 配置中,以将文件作为 Slidev 条目包含在内。默认值为`[“**/*.md”]`。例子: 60 | 61 | ```json 62 | { 63 | "slidev.include": ["**/presentation.md"] 64 | } 65 | ``` 66 | -------------------------------------------------------------------------------- /.vitepress/theme/components/FeatureTag.vue: -------------------------------------------------------------------------------- 1 | 52 | 53 | 67 | 68 | 80 | -------------------------------------------------------------------------------- /custom/config-fonts.md: -------------------------------------------------------------------------------- 1 | # 配置字体 2 | 3 | 虽然你可以使用 HTML 和 CSS 为你的幻灯片定制你想要的字体和样式,但 Slidev 提供了另一种较为便捷的方式让你更轻松地使用它们。 4 | 5 | 在你的 headmatter 中按如下方式配置: 6 | 7 | ```yaml 8 | --- 9 | fonts: 10 | # 基础字体 11 | sans: Robot 12 | # 与 UnoCSS 的 `font-serif` css 类一同使用 13 | serif: Robot Slab 14 | # 用于代码块、内联代码等 15 | mono: Fira Code 16 | --- 17 | ``` 18 | 19 | 按上述修改即可完成配置。 20 | 21 | 字体将**从 [Google Fonts](https://fonts.google.com/) 被自动**引入。这意味着你可以直接使用 Google Fonts 上的任何字体。 22 | 23 | ## 本地字体 24 | 25 | 默认情况下,Slidev 会认为 `fonts` 配置的所有字体均来自 Google Fonts。如果你想使用本地字体,可以指定 `fonts.local` 字段来选择不使用自动引入的字体。 26 | 27 | ```yaml 28 | --- 29 | fonts: 30 | # 与 css 中的 font-family 一致,你可以使用 `,` 来分割字体名,便于回退 31 | sans: 'Helvetica Neue,Robot' 32 | # 将 'Helvetica Neue' 作为本地字体 33 | local: Helvetica Neue 34 | --- 35 | ``` 36 | 37 | ## 字重 & 斜体 38 | 39 | 默认情况下,Slidev 为每种字体引入了三种 weight 大小 200,400,600。你可以按如下方式配置它们: 40 | 41 | ```yaml 42 | --- 43 | fonts: 44 | sans: Robot 45 | # 默认为 46 | weights: '200,400,600' 47 | # 引入斜体字体,默认 `false` 48 | italic: false 49 | --- 50 | ``` 51 | 52 | 这些配置适用于所有的网络字体。如果要对每种字体的 weight 进行更细粒度的控制,你需要用 [HTML](/custom/directory-structure.html#index-html) 和 CSS 手动引入它们。 53 | 54 | 55 | 56 | ## 字体回退 57 | 58 | 大多数情况下,只需指定 “特殊字体” 即可,Slidev 会为你提供可降级的字体。例如: 59 | 60 | ```yaml 61 | --- 62 | fonts: 63 | sans: Robot 64 | serif: Robot Slab 65 | mono: Fira Code 66 | --- 67 | ``` 68 | 69 | 其结果为: 70 | 71 | 72 | 73 | ```css 74 | .font-sans { 75 | font-family: "Robot",ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"; 76 | } 77 | .font-serif { 78 | font-family: "Robot Slab",ui-serif,Georgia,Cambria,"Times New Roman",Times,serif; 79 | } 80 | .font-mono { 81 | font-family: "Fira Code",ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace; 82 | } 83 | ``` 84 | 85 | 如需禁用降级字体,请按如下方式配置: 86 | 87 | ```yaml 88 | --- 89 | fonts: 90 | mono: 'Fira Code, monospace' 91 | fallbacks: false 92 | --- 93 | ``` 94 | 95 | ## 字体源 96 | 97 | - 选项: `google` | `none` 98 | - 默认值: `google` 99 | 100 | 目前,仅针对于 Google Fonts 进行了支持,我们计划在未来添加更多的字体服务整合。当此字段指定为 `none` 时,自动导入功能将被完全禁用,同时将所有字体视为本地字体。 101 | 102 | ```yaml 103 | --- 104 | fonts: 105 | provider: none 106 | --- 107 | ``` 108 | -------------------------------------------------------------------------------- /.vitepress/theme/components/ThemeInfo.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 78 | -------------------------------------------------------------------------------- /guide/faq.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # 常见问答 6 | 7 | ## 处理静态资源 {#assets-handling} 8 | 9 | 你可以在幻灯片中使用静态资源,如图片和视频。由于 Slidev 基于 Vite,你可以直接在 Markdown 文件中导入它们。 10 | 11 | 可用被静态分析的 URL 可以使用相对路径: 12 | 13 | ```md 14 | ![alt](./image.png) 15 | 16 | ``` 17 | 18 | 在上例中,URL 将在构建时被解析为 `/BASE_URL/assets/image.png`。 19 | 20 | 但是,frontmatter 和其他组件中的相对路径在构建后将会失效: 21 | 22 | ```md 23 | --- 24 | background: ./image.png # 构建后可能会失效 25 | --- 26 | 27 | 28 | ``` 29 | 30 | 上例中的两个 URL 不会被静态分析,构建后将保留原样,这将导致构建后的 404 错误。 31 | 32 | 要解决这个问题,你可以将这些资源放在 [public 文件夹](../custom/directory-structure#public) 中,并使用绝对路径导入它们: 33 | 34 | ```md 35 | --- 36 | background: /image.png 37 | --- 38 | 39 | 40 | ``` 41 | 42 | 更多细节请参阅 [Vite 的文档](https://cn.vitejs.dev/guide/assets.html). 43 | 44 | ## 定位元素 {#positioning} 45 | 46 | Slidev 基于 Web,CSS 是定位元素的主要方式。以下是一些有用的定位元素的技巧: 47 | 48 | ### Grids 和 Flexboxes {#grids-and-flexboxes} 49 | 50 | 可以使用 CSS Grids 来创建复杂的布局: 51 | 52 | ::: code-group 53 | 54 | ```md [双栏] 55 |
56 |
57 | 第一列 58 |
59 |
60 | 第二列 61 |
62 |
63 | ``` 64 | 65 | ```md [复杂布局] 66 |
67 |
68 | 第一列 (200px) 69 |
70 |
71 | 第二列 (auto fit) 72 |
73 |
74 | 第三列 (10% width to parent container) 75 |
76 |
77 | ``` 78 | 79 | ::: 80 | 81 | 或使用 Flexboxes 来创建更具响应性的布局: 82 | 83 | ::: code-group 84 | 85 | ```md [水平] 86 |
87 |
88 | 第一块 89 |
90 |
91 | 第二块 92 |
93 |
94 | ``` 95 | 96 | ```md [竖直] 97 |
98 |
99 | 居中的内容 100 |
101 |
102 | ``` 103 | 104 | ::: 105 | 106 | 了解更多:[CSS Grids](https://css-tricks.com/snippets/css/complete-guide-grid/),[flexboxes](https://css-tricks.com/snippets/css/a-guide-to-flexbox/),以及 [Masonry](https://css-tricks.com/native-css-masonry-layout-in-css-grid/)。 107 | 108 | ### 绝对定位 {#absolute-positioning} 109 | 110 | 可以使用 UnoCSS 来绝对定位元素: 111 | 112 | ```md 113 |
114 | 这是一个在左下角的页脚 115 |
116 | ``` 117 | 118 | 或者使用可拖动元素的功能: 119 | 120 | 121 | 122 | ## 调整大小 {#adjust-size} 123 | 124 | - 调整所有幻灯片的大小: 125 | 126 | 127 | 128 | - 调整某几张幻灯片的大小: 129 | 130 | 131 | 132 | - 调整一些元素的大小: 133 | 134 | 135 | -------------------------------------------------------------------------------- /custom/config-monaco.md: -------------------------------------------------------------------------------- 1 | # 配置 Monaco {#configure-monaco} 2 | 3 | 4 | 5 | 创建一份包含以下内容的 `./setup/monaco.ts` 文件: 6 | 7 | ```ts twoslash 8 | import { defineMonacoSetup } from '@slidev/types' 9 | 10 | export default defineMonacoSetup(async (monaco) => { 11 | // 使用 `monaco` 配置 12 | }) 13 | ``` 14 | 15 | 访问 [monaco-editor](https://github.com/Microsoft/monaco-editor) 了解更多关于 Monaco 配置的相关信息。 16 | 17 | ## TypeScript 类型 {#typescript-types} 18 | 19 | 当你使用 Monaco 编写 TypeScript 时,类型依赖将会自动安装到客户端. 20 | 21 | ````md 22 | ```ts {monaco} 23 | import { ref } from 'vue' 24 | import { useMouse } from '@vueuse/core' 25 | 26 | const counter = ref(0) 27 | ``` 28 | ```` 29 | 30 | 在上面的例子中,确保 `vue` 和 `@vueuse/core` 作为 dependencies 或 devDependencies 安装在本地,Slidev 将处理其余部分,以使编辑器自动使用这些类型。当部署为 SPA 时,这些类型也将被打包用于静态托管。 31 | 32 | 33 | ### 附加类型 {#additional-types} 34 | 35 | Slidev 将扫描幻灯片中的所有 Monaco 代码块,并帮助你导入所用库的类型。如果它有遗漏遗漏,你可以显式指定额外的包来导入相应类型: 36 | 37 | 38 | ```md 39 | --- 40 | monacoTypesAdditionalPackages: 41 | - lodash-es 42 | - foo 43 | --- 44 | ``` 45 | 46 | ### 自动类型获取 {#auto-type-acquisition} 47 | 48 | 你可以通过在 headmatter 通过以下设置切换到从CDN加载类型: 49 | 50 | ```md 51 | --- 52 | monacoTypesSource: ata 53 | --- 54 | ``` 55 | 56 | 此功能由 [`@typescript/ata`](https://github.com/microsoft/TypeScript-Website/tree/v2/packages/ata) 提供支持并且完全在客户端上运行。 57 | 58 | 59 | ## 配置主题 {#configure-themes} 60 | 61 | 自 v0.48.0 起,在[`@shikijs/Monaco`](https://shiki.style/packages/monaco)驱动下,Monaco 将复用你在 [Shiki 的设置文件](/custom/config-highlighter#configure-shiki) 中配置的 Shiki 主题。它将与你的其他代码块保持一致的风格。 62 | 63 | ## 配置编辑器 {#configure-the-editor} 64 | 65 | > 自 v0.43.0 起可用 66 | 67 | 如果你想自定义 Monaco 编辑器,可以传递一个匹配 [Monaco IEditorOptions](https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.IEditorOptions.html) 定义的 `editorOptions` 对象。 68 | 69 | 70 | ````md 71 | ```ts {monaco} { editorOptions: { wordWrap:'on'} } 72 | console.log('HelloWorld') 73 | ``` 74 | ```` 75 | 76 | 或者,如果你想将这些选项应用于每个 Monaco 实例,你可以在 `defineMonacoSetup` 函数中返回它们 77 | 78 | ```ts twoslash 79 | // ./setup/monaco.ts 80 | import { defineMonacoSetup } from '@slidev/types' 81 | 82 | export default defineMonacoSetup(() => { 83 | return { 84 | editorOptions: { 85 | wordWrap: 'on' 86 | } 87 | } 88 | }) 89 | ``` 90 | 91 | ## 禁用 {#disabling} 92 | 93 | 从v0.48.0开始,Monaco编辑器默认启用,但只你有使用到时才会被捆绑打包。如果你想禁用它,你可以在幻灯片的 frontmatter 中将 `Monaco` 设置为 `false`: 94 | 95 | ```yaml 96 | --- 97 | monaco: false # 也可以是 'dev' 或 'build' 来有条件地启用它 98 | --- 99 | ``` 100 | 101 | ## 配置代码运行器 {#configure-code-runners} 102 | 103 | 要配置Monaco Runner如何运行代码,或添加对自定义语言的支持,请参考 [配置代码运行器](/custom/config-code-runners)。 104 | -------------------------------------------------------------------------------- /features/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | editLink: false 3 | footer: false 4 | aside: false 5 | outline: false 6 | sidebar: false 7 | pageClass: all-features-page 8 | --- 9 | 10 | 42 | 43 | # 功能列表 44 | 45 | 本页是 Slidev 提供的相对独立的功能列表。每一个功能都可以在有需要的时候单独使用,使你的幻灯片更加精彩。 46 | 47 | 如果你想按主题了解这些功能,也可以阅读 。 48 | 49 |
50 |
55 | 56 | 61 |
62 |
66 | 67 | 68 |
69 |
70 | 71 | 72 | 73 |
74 | 找不到匹配的功能 75 | 79 |
80 | 81 | 86 | 87 | 92 | -------------------------------------------------------------------------------- /builtin/cli.md: -------------------------------------------------------------------------------- 1 | # Slidev 命令行工具 (CLI) 2 | 3 | `@slidev/cli` 提供了一个名为 `slidev` 的可执行命令,你可以用它来开发、构建和导出你的幻灯片。 4 | 5 | ## 基本信息 {#prerequisites} 6 | 7 | 可以通过全局安装 `@slidev/cli` 来使用 CLI,也可以在你的 Node.js 项目中本地安装。如果你的项目是通过 `npm init slidev` 创建的,则 CLI 已经被自动安装了。 8 | 9 | ::: warning 10 | 通常无法使用 `npx slidev`,因为包名实际上是 `@slidev/cli`。 11 | ::: 12 | 13 | 命令行选项遵循以下规则: 14 | 15 | - 选项的值可以在空格或 `=` 字符后传递: 16 | 17 | 例子: `slidev --port 8080` 等价于 `slidev --port=8080` 18 | 19 | - 对于布尔选项,`true` 值可以省略: 20 | 21 | 例子: `slidev --open` 等价于 `slidev --open true` 22 | 23 | ::: info 24 | 25 | 如果你使用 npm,请不要忘记在选项前加上 `--` 以将它们传递给 Slidev: 26 | 27 | ```bash 28 | npm run slidev -- --remote --port 8080 --open 29 | ``` 30 | 31 | ::: 32 | 33 | ## `slidev [entry]` {#dev} 34 | 35 | 启动一个本地 Slidev 服务器。 36 | 37 | - `[entry]` (`string`, 默认值: `slides.md`): 幻灯片的 markdown 文件路径. 38 | 39 | 选项: 40 | 41 | - `--port`, `-p` (`number`, 默认值: `3030`): 端口号 42 | - `--open`, `-o` (`boolean`, 默认值: `false`): 自动在浏览器中打开 43 | - `--remote [password]` (`string`): 监听公共主机并启用远程控制。如果传递了一个值,演示者模式将会是私有的,只能通过在URL中添加 `password` 的 query 来传递密码以访问。 44 | - `--bind` (`string`, 默认值: `0.0.0.0`): 指定服务器在远程模式下应监听哪些IP地址 45 | - `--log` (`'error', 'warn', 'info', 'silent'`, 默认值: `'warn'`): 日志等级 46 | - `--force`, `-f` (`boolean`, 默认值: `false`): 强制忽略缓存并重新打包 47 | - `--theme`, `-t` (`string`): 覆盖文件中设定的主题 48 | 49 | ## `slidev build [entry]` {#build} 50 | 51 | 构建一个可托管的 SPA。参阅 了解更多。 52 | 53 | - `[entry]` (`string`, default: `slides.md`): path to the slides markdown file. 54 | 55 | 选项: 56 | 57 | - `--out`, `-o` (`string`, 默认值: `dist`): 输出目录 58 | - `--base` (`string`, 默认值: `/`): 基本 URL (参考 https://vitejs.dev/config/shared-options.html#base) 59 | - `--download` (`boolean`, 默认值: `false`): 允许在构建后下载相应 幻灯片的 PDF 文件 60 | - `--theme`, `-t` (`string`): 覆盖文件中设定的主题 61 | 62 | ## `slidev export [...entry]` {#export} 63 | 64 | 将幻灯片导出为 PDF(或其他格式)。请参阅 以了解更多。 65 | 66 | - `[entry]` (`string`, 默认值: `slides.md`): 幻灯片的 markdown 文件路径 67 | 68 | 选项: 69 | 70 | - `--output` (`string`, 默认值: use `exportFilename` (参考 https://cn.sli.dev/custom/#frontmatter-configures) 或使用 `[entry]-export`): 导出的路径. 71 | - `--format` (`'pdf', 'png', 'md'`, 默认值: `'pdf'`): 输出格式. 72 | - `--timeout` (`number`, 默认值: `30000`): 渲染打印页面的超时时间 (参考 https://playwright.dev/docs/api/class-page#page-goto) 73 | - `--range` (`string`): 导出的页面范围 (示例: `'1,4-5,6'`). 74 | - `--dark` (`boolean`, 默认值: `false`): 导出为暗黑模式 75 | - `--with-clicks`, `-c` (`boolean`, 默认值: `false`): 为每次点击分别导出 (参考 https://cn.sli.dev/guide/animations.html#click-animations). 76 | - `--theme`, `-t` (`string`): 覆盖文件中设定的主题 77 | - `--omit-background` (`boolean`, default: `false`): 不导出浏览器默认的背景色 78 | 79 | ## `slidev format [entry]` {#format} 80 | 81 | 格式化 markdown 文件。请注意,这不会格式化幻灯片的内容,只会格式化 markdown 文件的组织结构。 82 | 83 | - `[entry]` (`string`, 默认值: `slides.md`): 幻灯片的 markdown 文件路径 84 | 85 | ## `slidev theme [subcommand]` {#theme} 86 | 87 | 主题相关的操作。 88 | 89 | 子命令: 90 | 91 | - `eject [entry]`: 将当前主题弹出到本地文件中 92 | - `[entry]` (`string`, 默认值: `slides.md`): 幻灯片的 markdown 文件路径 93 | - 选项: 94 | - `--dir` (`string`, 默认值: `theme`): 输出文件夹 95 | - `--theme`, `-t` (`string`): 覆盖文件中设定的主题 96 | -------------------------------------------------------------------------------- /builtin/layouts.md: -------------------------------------------------------------------------------- 1 | # 内置布局 2 | 3 | 本页列出了 Slidev 提供的所有内置布局。这些布局可以通过幻灯片的 frontmatter 中的 `layout` 选项来使用。 4 | 5 | 需要注意的是, 可以提供额外的布局。要添加自己的布局,请参见 。 6 | 7 | ## `center` 8 | 9 | 在屏幕中间展示内容。 10 | 11 | ## `cover` 12 | 13 | 用来展示演讲稿的封面页,可以包含演讲的标题、演讲者、时间等。 14 | 15 | ## `default` 16 | 17 | 最基础的布局,用于展示任意类型的内容。 18 | 19 | ## `end` 20 | 21 | 演讲的最后一页。 22 | 23 | ## `fact` 24 | 25 | 用来在屏幕上突出展示很多事实或数据。 26 | 27 | ## `full` 28 | 29 | 使用屏幕全部空间来展示内容。 30 | 31 | ## `image-left` 32 | 33 | 在屏幕左侧展示图片,屏幕右侧展示内容。 34 | 35 | ### 用法 36 | 37 | ```yaml 38 | --- 39 | layout: image-left 40 | 41 | # 图片来源 42 | image: /path/to/the/image 43 | 44 | # 内容的自定义 class 名称 45 | class: my-cool-content-on-the-right 46 | --- 47 | ``` 48 | 49 | ## `image-right` 50 | 51 | 在屏幕右侧展示图片,屏幕左侧展示内容。 52 | 53 | ### 用法 54 | 55 | ```yaml 56 | --- 57 | layout: image-right 58 | 59 | # 图片来源 60 | image: /path/to/the/image 61 | 62 | # 内容的自定义 class 名称 63 | class: my-cool-content-on-the-left 64 | --- 65 | ``` 66 | 67 | ## `image` 68 | 69 | 将图片作为页面的主要内容进行展示。 70 | 71 | ### 用法 72 | 73 | ```yaml 74 | --- 75 | layout: image 76 | 77 | # 图片来源 78 | image: /path/to/the/image 79 | --- 80 | ``` 81 | 82 | 你可以使用 `backgroundSize` 选项来控制背景图片的大小: 83 | 84 | ```yaml 85 | --- 86 | layout: image 87 | image: /path/to/the/image 88 | backgroundSize: contain 89 | --- 90 | ``` 91 | 92 | ```yaml 93 | --- 94 | layout: image-left 95 | image: /path/to/the/image 96 | backgroundSize: 20em 70% 97 | --- 98 | ``` 99 | 100 | ## `iframe-left` 101 | 102 | 在屏幕左侧通过 ` 113 | -------------------------------------------------------------------------------- /.vitepress/sidebar-gen.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url' 2 | import { join } from 'node:path' 3 | import fg from 'fast-glob' 4 | import type { DefaultTheme } from 'vitepress' 5 | import graymatter from 'gray-matter' 6 | 7 | const root = fileURLToPath(new URL('../', import.meta.url)) 8 | 9 | interface ParsedFile { 10 | filepath: string 11 | path: string 12 | matter: graymatter.GrayMatterFile 13 | title: string 14 | } 15 | 16 | function parseFile(file: string) { 17 | const filepath = join(root, file) 18 | const path = file.replace('.md', '') 19 | const matter = graymatter.read(filepath) 20 | const title = matter.data.title || matter.content.match(/^#\s+(.*)/m)?.[1] || path 21 | return { 22 | filepath, 23 | path, 24 | matter, 25 | title, 26 | } 27 | } 28 | 29 | export async function getSidebarObject() { 30 | const map: Record = {} 31 | 32 | const parsedFeatures: ParsedFile[] = await fg([ 33 | 'features/*.md', 34 | ], { 35 | onlyFiles: true, 36 | cwd: root, 37 | }) 38 | .then(files => files.map(parseFile)) 39 | 40 | const parsedGuides: ParsedFile[] = await fg([ 41 | 'guide/*.md', 42 | ], { 43 | onlyFiles: true, 44 | cwd: root, 45 | }) 46 | .then(files => files.map(parseFile)) 47 | 48 | parsedFeatures.forEach(({ matter, path }) => { 49 | const items: DefaultTheme.SidebarItem[] = [ 50 | { 51 | text: '返回', 52 | items: [ 53 | { 54 | text: '功能列表', 55 | link: '/features', 56 | }, 57 | ], 58 | }, 59 | ] 60 | 61 | function findParsed(related: string) { 62 | related = related.replace(/#.*$/, '') 63 | const feature = parsedFeatures.find(file => file.path === related) 64 | if (feature) { 65 | return { 66 | type: 'features', 67 | item: feature, 68 | } 69 | } 70 | const guide = parsedGuides.find(file => file.path === related) 71 | if (guide) { 72 | return { 73 | type: 'guide', 74 | item: guide, 75 | } 76 | } 77 | return undefined 78 | } 79 | 80 | function frontmatterToSidebarItem(path: string | Record): DefaultTheme.SidebarItem[] { 81 | if (typeof path === 'string') { 82 | const match = findParsed(path) 83 | if (match?.type === 'features') { 84 | return [{ 85 | text: `✨ ${match.item.title}`, 86 | link: `/${match.item.path}`, 87 | }] 88 | } 89 | if (match?.type === 'guide') { 90 | return [{ 91 | text: `📖 ${match.item.title}`, 92 | link: `/${match.item.path}`, 93 | }] 94 | } 95 | console.warn(`Dependent file not found: ${path}`) 96 | return [{ 97 | text: path, 98 | link: `/${path}`, 99 | }] 100 | } 101 | else { 102 | return Object.entries(path).map(([text, link]) => ({ 103 | text, 104 | link, 105 | })) 106 | } 107 | } 108 | 109 | if (matter.data.depends) { 110 | items.push({ 111 | text: '基于', 112 | items: matter.data.depends.flatMap(frontmatterToSidebarItem), 113 | }) 114 | } 115 | 116 | if (matter.data.relates) { 117 | items.push({ 118 | text: '相关链接', 119 | items: matter.data.relates.flatMap(frontmatterToSidebarItem), 120 | }) 121 | } 122 | 123 | const derives = matter.data.derives 124 | ?? parsedFeatures.filter(f => f.matter.data.depends?.includes(path)).map(f => f.path) 125 | 126 | if (derives.length) { 127 | items.push({ 128 | text: '派生功能', 129 | items: derives.flatMap(frontmatterToSidebarItem), 130 | }) 131 | } 132 | 133 | map[`/${path}`] = items 134 | }) 135 | 136 | return map 137 | } 138 | -------------------------------------------------------------------------------- /.vitepress/theme/styles/demo.css: -------------------------------------------------------------------------------- 1 | html:not(.dark) { 2 | --prism-foreground: #393a34; 3 | --prism-background: #fafafa; 4 | --prism-inline-background: #f5f5f5; 5 | --prism-comment: #a0ada0; 6 | --prism-string: #b56959; 7 | --prism-literal: #2f8a89; 8 | --prism-number: #296aa3; 9 | --prism-keyword: #1c6b48; 10 | --prism-function: #6c7834; 11 | --prism-boolean: #296aa3; 12 | --prism-constant: #a65e2b; 13 | --prism-deleted: #a14f55; 14 | --prism-class: #2993a3; 15 | --prism-builtin: #ab5959; 16 | --prism-property: #b58451; 17 | --prism-namespace: #b05a78; 18 | --prism-punctuation: #8e8f8b; 19 | --prism-decorator: #bd8f8f; 20 | --prism-regex: #ab5e3f; 21 | --prism-json-property: #698c96; 22 | } 23 | 24 | html.dark { 25 | --prism-scheme: dark; 26 | --prism-foreground: #d4cfbf; 27 | --prism-background: #181818; 28 | --prism-comment: #758575; 29 | --prism-string: #d48372; 30 | --prism-literal: #429988; 31 | --prism-keyword: #4d9375; 32 | --prism-boolean: #6394bf; 33 | --prism-number: #6394bf; 34 | --prism-variable: #c2b36e; 35 | --prism-function: #a1b567; 36 | --prism-deleted: #bc6066; 37 | --prism-class: #54b1bf; 38 | --prism-builtin: #e0a569; 39 | --prism-property: #dd8e6e; 40 | --prism-namespace: #db889a; 41 | --prism-punctuation: #858585; 42 | --prism-decorator: #bd8f8f; 43 | --prism-regex: #ab5e3f; 44 | --prism-json-property: #6b8b9e; 45 | --prism-line-number: #888888; 46 | --prism-line-number-gutter: #eeeeee; 47 | --prism-line-highlight-background: #444444; 48 | --prism-selection-background: #444444; 49 | --prism-inline-background: theme('colors.dark.300'); 50 | } 51 | 52 | .token.title { 53 | color: var(--prism-keyword); 54 | } 55 | 56 | .token.comment, 57 | .token.prolog, 58 | .token.doctype, 59 | .token.cdata { 60 | color: var(--prism-comment); 61 | font-style: var(--prism-comment-style); 62 | } 63 | 64 | .token.namespace { 65 | color: var(--prism-namespace); 66 | } 67 | 68 | .token.interpolation { 69 | color: var(--prism-interpolation); 70 | } 71 | 72 | .token.string { 73 | color: var(--prism-string); 74 | } 75 | 76 | .token.punctuation { 77 | color: var(--prism-punctuation); 78 | } 79 | 80 | .token.operator { 81 | color: var(--prism-operator); 82 | } 83 | 84 | .token.keyword.module, 85 | .token.keyword.control-flow { 86 | color: var(--prism-keyword-control); 87 | } 88 | 89 | .token.url, 90 | .token.symbol, 91 | .token.inserted { 92 | color: var(--prism-symbol); 93 | } 94 | 95 | .token.constant { 96 | color: var(--prism-constant); 97 | } 98 | 99 | .token.string.url { 100 | text-decoration: var(--prism-url-decoration); 101 | } 102 | 103 | .token.boolean, 104 | .language-json .token.boolean { 105 | color: var(--prism-boolean); 106 | } 107 | 108 | .token.number, 109 | .language-json .token.number { 110 | color: var(--prism-number); 111 | } 112 | 113 | .token.variable { 114 | color: var(--prism-variable); 115 | } 116 | 117 | .token.keyword { 118 | color: var(--prism-keyword); 119 | } 120 | 121 | .token.atrule, 122 | .token.attr-value, 123 | .token.selector { 124 | color: var(--prism-selector); 125 | } 126 | 127 | .token.function { 128 | color: var(--prism-function); 129 | } 130 | 131 | .token.deleted { 132 | color: var(--prism-deleted); 133 | } 134 | 135 | .token.important, 136 | .token.bold { 137 | font-weight: bold; 138 | } 139 | 140 | .token.italic { 141 | font-style: italic; 142 | } 143 | 144 | .token.class-name { 145 | color: var(--prism-class); 146 | } 147 | 148 | .token.tag, 149 | .token.builtin { 150 | color: var(--prism-builtin); 151 | } 152 | 153 | .token.attr-name, 154 | .token.property, 155 | .token.entity { 156 | color: var(--prism-property); 157 | } 158 | 159 | .language-json .token.property { 160 | color: var(--prism-json-property); 161 | } 162 | 163 | .token.regex { 164 | color: var(--prism-regex); 165 | } 166 | 167 | .token.decorator, 168 | .token.annotation { 169 | color: var(--prism-decorator); 170 | } 171 | -------------------------------------------------------------------------------- /guide/syntax.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # 语法 6 | 7 | Slidev 的幻灯片是用 Markdown 文件编写的,称为 **Slidev Markdown**。演示文稿由一个 Slidev Markdown 作为入口点,该文件默认为 `./slides.md`,你可以将文件路径作为参数传递给 [CLI 命令](../builtin/cli) 来使用别的文件。 8 | 9 | 在 Slidev Markdown 中,不仅可以像平常一样使用 [基本的 Markdown 功能](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet),Slidev 还提供了额外的功能来增强你的幻灯片。本节介绍了 Slidev 引入的语法。请确保你了解基本的 Markdown 语法后再阅读本指南。 10 | 11 | ## 分隔符 {#slide-separators} 12 | 13 | 使用在两侧留有空行的 `---` 来分隔幻灯片: 14 | 15 | ````md {5,15} 16 | # Title 17 | 18 | Hello, **Slidev**! 19 | 20 | --- 21 | 22 | # Slide 2 23 | 24 | 使用代码块来高亮代码: 25 | 26 | ```ts 27 | console.log('Hello, World!') 28 | ``` 29 | 30 | --- 31 | 32 | # Slide 3 33 | 34 | 使用 UnoCSS 类和 Vue 组件来为你的幻灯片添加样式和丰富内容: 35 | 36 |
37 | 38 |
39 | ```` 40 | 41 | ## Frontmatter 和 Headmatter {#frontmatter} 42 | 43 | 在每张幻灯片的开头,你可以添加一个可选的 [frontmatter](https://jekyllrb.com/docs/front-matter/) 来配置幻灯片。第一个 frontmatter 块称为 **headmatter**,可以配置整个幻灯片集。其余的是用于单个幻灯片的 **frontmatters**。headmatter 或 frontmatter 中的文本应是 [YAML](https://www.cloudbees.com/blog/yaml-tutorial-everything-you-need-get-started/) 格式的对象。例如: 44 | 45 | 46 | 47 | ```md {1-4,10-14,26-28} 48 | --- 49 | theme: seriph 50 | title: Welcome to Slidev 51 | --- 52 | 53 | # 第一页 54 | 55 | 第一页的 frontmatter 也是整个演示文稿的 headmatter 56 | 57 | --- 58 | layout: center 59 | background: /background-1.png 60 | class: text-white 61 | --- 62 | 63 | # 第二页 64 | 65 | 本页的布局是 `center`,背景是一张图片 66 | 67 | --- 68 | 69 | # 第三页 70 | 71 | 本页没有 frontmatter 72 | 73 | --- 74 | src: ./pages/4.md # 本页只包含 frontmatter 75 | --- 76 | 77 | --- 78 | 79 | # 第五页 80 | ``` 81 | 82 | 具体的配置项请参考 [演示文稿的配置](/custom/#headmatter) 和 [每个幻灯片的配置](/custom/#frontmatter) 部分。 83 | 84 | 你还可以安装 VSCode 扩展来使 headmatter 更易读: 85 | 86 | 87 | 88 | 还可以使用另一种 frontmatter 格式: 89 | 90 | 91 | 92 | ## 备注 {#notes} 93 | 94 | 每张幻灯片的末尾的注释块(若有),将被视为幻灯片的备注。它们将在 中显示,以供您在演示过程中参考。 95 | 96 | ```md {9,19-21} 97 | --- 98 | layout: cover 99 | --- 100 | 101 | # 第一页 102 | 103 | 封面页 104 | 105 | 106 | 107 | --- 108 | 109 | # 第二页 110 | 111 | 112 | 113 | 第二页的内容 114 | 115 | 118 | ``` 119 | 120 | 备注中也支持渲染 Markdown 和 HTML。 121 | 122 | 125 | 126 | ## 代码块 {#code-block} 127 | 128 | 创建 Slidev 的一个重要原因是需要在幻灯片中完美地显示代码。在 Slidev 中,你可以使用 Markdown 风格的代码块来高亮你的代码。 129 | 130 | ````md 131 | ```ts 132 | console.log('Hello, World!') 133 | ``` 134 | ```` 135 | 136 | Slidev 使用 [Shiki](https://github.com/shikijs/shiki) 作为语法高亮器。有关更多详细信息,请参阅 [配置 Shiki](/custom/config-highlighter)。 137 | 138 | 与代码块相关的更多内容: 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | ## Latex 公式块 {#latex-block} 151 | 152 | Slidev 支持用于渲染数学和化学公式的 LaTeX 公式块: 153 | 154 | 155 | 156 | ## 图表 {#diagrams} 157 | 158 | Slidev 支持使用 [Mermaid.js](http://mermaid.js.org/) 和 [PlantUML](https://plantuml.com/),以文本形式创建图表: 159 | 160 | 161 | 162 | 163 | ## MDC 语法 {#mdc-syntax} 164 | 165 | MDC 语法是将样式和类应用于元素的最简单方法: 166 | 167 | 168 | 169 | ## Scoped CSS {#scoped-css} 170 | 171 | Scoped CSS 可以用来为你的幻灯片添加样式: 172 | 173 | 174 | 175 | ## 导入幻灯片 {#importing-slides} 176 | 177 | 178 | -------------------------------------------------------------------------------- /guide/exporting.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # 导出幻灯片 6 | 7 | 通常幻灯片在浏览器中显示,但你也可以将它们导出为 PDF、PPTX、PNG 或 Markdown 文件以便分享或打印。这个功能通过 CLI 命令 [`slidev export`](../builtin/cli#export) 实现。 8 | 9 | 但是,幻灯片中的交互式功能在导出的文件中可能无法使用。你也可以构建和托管你的幻灯片作为 Web 应用程序以保留交互性。请参阅 [构建和托管](./hosting) 了解更多信息。 10 | 11 | ## 准备工作 {#preparation} 12 | 13 | 导出为 PDF、PPTX 或 PNG 依赖于 [Playwright](https://playwright.dev) 来渲染幻灯片。因此,你需要在你的项目中安装 [`playwright-chromium`](https://npmjs.com/package/playwright-chromium): 14 | 15 | ::: code-group 16 | 17 | ```bash [npm] 18 | $ npm i -D playwright-chromium 19 | ``` 20 | 21 | ```bash [pnpm] 22 | $ pnpm add -D playwright-chromium 23 | ``` 24 | 25 | ```bash [yarn] 26 | $ yarn add -D playwright-chromium 27 | ``` 28 | 29 | ::: 30 | 31 | ## 支持的格式 {#formats} 32 | 33 | ### PDF 34 | 35 | 在安装了 `playwright-chromium` 之后,你可以使用以下命令将幻灯片导出为 PDF: 36 | 37 | ```bash 38 | $ slidev export 39 | ``` 40 | 41 | 默认地,PDF 文件会被导出到 `./slides-export.pdf`。 42 | 43 | ### PPTX 44 | 45 | Slidev 也可以将你的幻灯片导出为 PPTX 文件: 46 | 47 | ```bash 48 | $ slidev export --format pptx 49 | ``` 50 | 51 | 需要注意的是,PPTX 文件中的所有幻灯片都会被导出为图片,因此文本不可选择。演讲者备注将以每张幻灯片为单位传递到 PPTX 文件中。 52 | 53 | 在此模式下,默认启用了 `--with-clicks` 选项。要禁用它,请传递 `--with-clicks false`。 54 | 55 | ### PNGs 或 Markdown {#pngs-and-markdown} 56 | 57 | 当传递 `--format png` 选项时,Slidev 会为每张幻灯片导出 PNG 图像而不是 PDF: 58 | 59 | ```bash 60 | $ slidev export --format png 61 | ``` 62 | 63 | 你也可以使用 `--format md` 选项将幻灯片导出为 Markdown 文件: 64 | 65 | ```bash 66 | $ slidev export --format md 67 | ``` 68 | 69 | ## 选项 {#options} 70 | 71 | 以下是一些常用的 `slidev export` 命令选项。更多选项请参阅 [CLI 文档](../builtin/cli#export)。 72 | 73 | ### 导出动画步骤 {#export-clicks-steps} 74 | 75 | 默认地,Slidev 会将每张幻灯片导出为一个页面,不包含点击动画。如果你想要将幻灯片的多个步骤导出为多个页面,可以传递 `--with-clicks` 选项: 76 | 77 | ```bash 78 | $ slidev export --with-clicks 79 | ``` 80 | 81 | ### 指定导出文件名 {#output-filename} 82 | 83 | 你可以使用 `--output` 选项指定导出文件名: 84 | 85 | ```bash 86 | $ slidev export --output my-pdf-export 87 | ``` 88 | 89 | 或在 headmatter 中指定: 90 | 91 | ```yaml 92 | --- 93 | exportFilename: my-pdf-export 94 | --- 95 | ``` 96 | 97 | ### 限定导出范围 {#export-with-range} 98 | 99 | 默认情况下,会导出演示文稿中的所有幻灯片。如果你想要导出特定幻灯片或幻灯片范围,可以使用 `--range` 选项并指定你想要导出的幻灯片: 100 | 101 | ```bash 102 | $ slidev export --range 1,6-8,10 103 | ``` 104 | 105 | 该选项接收特定的幻灯片编号或范围。上例会导出第 1、6、7、8 和 10 张幻灯片。 106 | 107 | ### 多个幻灯片 {#multiple-slides} 108 | 109 | 你可以一次导出多个幻灯片: 110 | 111 | ```bash 112 | $ slidev export slides1.md slides2.md 113 | ``` 114 | 115 | 或者使用通配符(仅在部分 shell 下有效): 116 | 117 | ```bash 118 | $ slidev export *.md 119 | ``` 120 | 121 | 在这种情况下,每个输入文件都会生成自己的 PDF 文件。 122 | 123 | ### 暗色模式 {#dark-mode} 124 | 125 | 若要使用主题的暗色版本导出幻灯片,可以使用 `--dark` 选项: 126 | 127 | ```bash 128 | $ slidev export --dark 129 | ``` 130 | 131 | ### 超时 {#timeout} 132 | 133 | 对于非常大的演示文稿,你可能需要增加 Playwright 的超时时间: 134 | 135 | ```bash 136 | $ slidev export --timeout 60000 137 | ``` 138 | 139 | ### 等待 {#wait} 140 | 141 | 一些幻灯片可能需要更长的时间来加载和渲染。你可以使用 `--wait` 选项在导出之前等待一段时间: 142 | 143 | ```bash 144 | $ slidev export --wait 10000 145 | ``` 146 | 147 | 此外,还有一个 `--wait-until` 选项,用于在导出每张幻灯片之前等待一个状态。如果你一直遇到超时问题,可以尝试设置此选项: 148 | 149 | ```bash 150 | $ slidev export --wait-until none 151 | ``` 152 | 153 | 该选项接受以下值之一: 154 | 155 | - `'networkidle'` - (_默认_)当没有网络连接至少 `500` 毫秒时,认为操作已完成。这是最安全的,但可能会导致超时。 156 | - `'domcontentloaded'` - 当 `DOMContentLoaded` 事件被触发时,认为操作已完成。 157 | - `'load'` - 当 `load` 事件被触发时,认为操作已完成。 158 | - `'none'` - 不等待任何事件。 159 | 160 | ::: warning 161 | 如果指定了 `'networkidle'` 之外的值,请确保打印的幻灯片是完整且正确的。如果某些内容丢失,你可能需要使用 `--wait` 选项。 162 | ::: 163 | 164 | ### 可执行文件路径 {#executable-path} 165 | 166 | Chromium 可能缺少一些解码某些视频所需的编解码器等功能。你可以使用 `--executable-path` 选项将 Playwright 的浏览器可执行文件路径设置为 Chrome 或 Edge: 167 | 168 | ```bash 169 | $ slidev export --executable-path [path_to_chromium] 170 | ``` 171 | 172 | ### PDF 大纲 {#pdf-outline} 173 | 174 | > 自 v0.36.10 起可用 175 | 176 | 你可以通过传递 `--with-toc` 选项生成 PDF 大纲: 177 | 178 | ```bash 179 | $ slidev export --with-toc 180 | ``` 181 | 182 | ### 去除背景 183 | 184 | 在导出为 PNG图像时,你可以通过传递 `--omit-background` 选项去除默认的浏览器背景: 185 | 186 | ```bash 187 | $ slidev export --omit-background 188 | ``` 189 | 190 | 默认浏览器背景是所有浏览器窗口上可见的白色背景。它与在整个应用中使用CSS样式呈现的其他背景不同。请参阅 [Playwright 的文档](https://playwright.dev/docs/api/class-page#page-screenshot-option-omit-background)。此外,你需要应用额外的CSS样式以显示透明度。 191 | 192 | 以下是一个示例,覆盖了应用中的所有背景: 193 | 194 | ```css 195 | * { 196 | background: transparent !important; 197 | } 198 | ``` 199 | -------------------------------------------------------------------------------- /custom/config-parser.md: -------------------------------------------------------------------------------- 1 | # 配置预解析器 2 | 3 | ::: info 4 | 5 | 自定义的预解析器应尽可能少地使用。通常,你可以使用 [Transformers](./config-transformers) 进行自定义语法。 6 | 7 | ::: 8 | 9 | Slidev 通过三步解析演示文档(如 `slides.md`) : 10 | 11 | 1. 执行一个“预解析”步骤: 使用 `---` 分隔符将 markdown 文件分割成若干幻灯片,并考虑可能的扉页块。 12 | 2. 每张幻灯片都用一个外部库进行解析。 13 | 3. Slidev 解析特殊的扉页属性 `src: ....`,该属性允许包含其他 md 文件。 14 | 15 | ## Markdown 解析器 16 | 17 | 配置步骤2中使用的markdown解析器可以通过 [配置Vite内部插件](/custom/config-vite#configure-internal-plugins) 完成。 18 | 19 | ## 预解析器扩展 20 | 21 | > 自 v0.37.0 起可用。 22 | 23 | ::: warning 24 | 25 | 重要:当你修改预解析器配置时,需要停止并重新启动 slidev。 26 | 27 | ::: 28 | 29 | 预解析器(上面的步骤 1)是高度可扩展的,并且允许为 md 文件实现自定义语法。扩展预解析器是一个**高级特性**,由于语法的隐式更改,它很容易破坏[编辑器集成](../features/side-editor)。 30 | 31 | 要自定义它,请创建一个 `./setup/prepareser.ts` 文件,内容如下: 32 | 33 | ```ts twoslash 34 | import { definePreparserSetup } from '@slidev/types' 35 | 36 | export default definePreparserSetup(({ filepath, headmatter, mode }) => { 37 | return [ 38 | { 39 | transformRawLines(lines) { 40 | for (const i in lines) { 41 | if (lines[i] === '@@@') 42 | lines[i] = 'HELLO' 43 | } 44 | }, 45 | } 46 | ] 47 | }) 48 | ``` 49 | 50 | 这个例子系统地将任何 `@@@` 行替换为 `hello` 行。它说明了预解析器配置文件的结构以及其涉及的一些主要概念: 51 | 52 | - 必须使用函数调用 `definePreparerSetup` 作为参数。 53 | - 该函数接收(根演示文稿的)文件路径、headatter(来自相应的 md 文件)以及自 v0.48.0 起,一种模式(dev、build 或 export)。它可以使用这些信息(例如,根据演示文稿文件,或者我们是否正在导出PDF,来启用扩展)。 54 | - 该函数必须返回一个预解析器扩展列表。 55 | - 一个扩展可以包含以下内容: 56 | - 一个 `transformRawLines(lines)` 函数,在解析 md 文件的 headmatter 后运行,并接收所有行的列表(来自 md 文件)。该函数可以任意修改列表。 57 | - 一个 `transformSlide(content,frontmatter)`函数,在分割文件后,为每张幻灯片调用该函数,并将幻灯片内容作为字符串接收,将幻灯片的 frontmatter 作为对象接收。该函数可以修改 frontmatter,并且必须返回内容字符串(可能已修改,如果没有进行修改,则可能为 `undefined`)。 58 | - 一个 `name` 59 | 60 | ## 预解析器扩展示例 61 | 62 | ### 用例1: 紧凑语法顶层表示 63 | 64 | 设想一种情况,你的演示文稿(部分)主要显示封面图片,并包括其他 md 文件。你可能希望有一种紧凑的符号表示法,其中的实例(部分)`slides.md` 如下所示: 65 | 66 | 67 | 68 | ```md 69 | @cover: /nice.jpg 70 | # Welcome 71 | @src: page1.md 72 | @src: page2.md 73 | @cover: /break.jpg 74 | @src: pages3-4.md 75 | @cover: https://cover.sli.dev 76 | # Questions? 77 | see you next time 78 | ``` 79 | 80 | 要允许这些 `@src:` 和 `@cover:` 语法,请创建一个 `/setup/prepareser.ts`文件,内容如下: 81 | 82 | 83 | ```ts twoslash 84 | import { definePreparserSetup } from '@slidev/types' 85 | 86 | export default definePreparserSetup(() => { 87 | return [ 88 | { 89 | transformRawLines(lines) { 90 | let i = 0 91 | while (i < lines.length) { 92 | const l = lines[i] 93 | if (l.match(/^@cover:/i)) { 94 | lines.splice( 95 | i, 96 | 1, 97 | '---', 98 | 'layout: cover', 99 | `background: ${l.replace(/^@cover: */i, '')}`, 100 | '---', 101 | '' 102 | ) 103 | continue 104 | } 105 | if (l.match(/^@src:/i)) { 106 | lines.splice( 107 | i, 108 | 1, 109 | '---', 110 | `src: ${l.replace(/^@src: */i, '')}`, 111 | '---', 112 | '' 113 | ) 114 | continue 115 | } 116 | i++ 117 | } 118 | } 119 | }, 120 | ] 121 | }) 122 | ``` 123 | 124 | 就是这样。 125 | 126 | ### 用例2:使用自定义 frontmatter 来包装幻灯片 127 | 128 | 设想一种情况,你经常想要缩放您的一些幻灯片,但是仍然想要使用各种现有的布局,因此创建一个新的布局将不适合。例如,你可能希望按如下方式编写 `slides.md`: 129 | 130 | 131 | 132 | ```md 133 | --- 134 | layout: quote 135 | _scale: 0.75 136 | --- 137 | 138 | # Welcome 139 | 140 | > great! 141 | 142 | --- 143 | _scale: 4 144 | --- 145 | # Break 146 | 147 | --- 148 | 149 | # Ok 150 | 151 | --- 152 | layout: center 153 | _scale: 2.5 154 | --- 155 | # Questions? 156 | see you next time 157 | ``` 158 | 159 | 在这里,我们在 `_scale` 处使用了下划线,以避免与现有的 frontmatter 属性发生可能的冲突(事实上,没有下划线的 `scale` 的情况会导致潜在的问题)。 160 | 161 | 要处理这个 `_scale: ...`语法,在 frontmatter 中创建一个 `./setup/preparser.ts` 文件,内容如下: 162 | 163 | ```ts twoslash 164 | import { definePreparserSetup } from '@slidev/types' 165 | 166 | export default definePreparserSetup(() => { 167 | return [ 168 | { 169 | async transformSlide(content, frontmatter) { 170 | if ('_scale' in frontmatter) { 171 | return [ 172 | ``, 173 | '', 174 | content, 175 | '', 176 | '' 177 | ].join('\n') 178 | } 179 | }, 180 | }, 181 | ] 182 | }) 183 | ``` 184 | -------------------------------------------------------------------------------- /guide/ui.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # 用户界面 6 | 7 | ## 导航栏 {#navigation-bar} 8 | 9 | 在播放模式下,导航栏在页面的左下角。可能需要将鼠标移动到页面的左下角才能看到导航栏。 10 | 11 | ![](/screenshots/navbar.png) 12 | 13 | > 你可以通过 来扩展导航栏的内容。 14 | 15 | ## 导航操作 {#navigation-actions} 16 | 17 | | 快捷键 | 导航栏按钮 | 说明 | 18 | | ----------------------------------- | ------------------------------------------------------------------------------------- | --------------------------------------------------------------- | 19 | | f | | 切换全屏模式 | 20 | | right / space | | 下一个动画或幻灯片 | 21 | | left | | 上一个动画或幻灯片 | 22 | | up | - | 上一页幻灯片 | 23 | | down | - | 下一页幻灯片 | 24 | | o | | 打开 [幻灯片总览](#quick-overview) | 25 | | d | | 切换暗色模式 | 26 | | - | | 开启 [摄像头视图](../features/recording#camera-view) | 27 | | - | | 开启 | 28 | | - | | 进入 [演讲者模式](#presenter-mode) | 29 | | - | | 打开或关闭 | 30 | | - | | 下载 PDF。参见 | 31 | | - | | 查看幻灯片的信息 | 32 | | - | | 查看设置菜单 | 33 | | g | - | 打开跳转对话框 | 34 | 35 | > Slidev 支持 [自定义快捷键](../custom/config-shortcuts)。 36 | 37 | ## 幻灯片总览 {#quick-overview} 38 | 39 | 通过点击 o 键或点击导航栏中的 按钮,你可以查看幻灯片的总览,以便快速地跳转至某幻灯片。 40 | 41 | ![](/screenshots/slides-overview.png) 42 | 43 | ## 演讲者模式 {#presenter-mode} 44 | 45 | 点击 按钮或访问 `http://localhost:/presenter` 来进入演讲者模式。 46 | 47 | 在演讲中,建议打开两个浏览器窗口 - 一个在播放模式用于观众,另一个在演讲者模式用于你。然后你可以将第一个屏幕分享给观众,保留第二个屏幕给自己。每当你在演讲者模式中导航时,观众的屏幕也会同步更新。 48 | 49 | ![](/screenshots/presenter-mode.png) 50 | 51 | ## 幻灯片列表 {#slides-overview} 52 | 53 | > 自 v0.48.0 起可用 54 | 55 | 57 | 58 | 首先打开 [幻灯片总览](#quick-overview),然后点击右上角的 ,或直接访问 `http://localhost:/overview`,即可进入幻灯片列表页面。 59 | 60 | 幻灯片列表页面会给你一个线性列表,包含所有幻灯片的注释。你可以双击注释来直接编辑,也可以拖动点击滑块来预览幻灯片的步骤。 61 | 62 | ## 绘图 {#drawing} 63 | 64 | 请参阅: 65 | 66 | 67 | 68 | ## 录制工具 {#recording} 69 | 70 | 请参阅: 71 | 72 | 73 | 74 | ## 全局图层 {#global-layers} 75 | 76 | 可以在全局或对每张幻灯片的上方或下方添加任何自定义 UI: 77 | 78 | 79 | -------------------------------------------------------------------------------- /.vitepress/config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url' 2 | import type { DefaultTheme } from 'vitepress' 3 | import { defineConfig } from 'vitepress' 4 | import { transformerTwoslash } from '@shikijs/vitepress-twoslash' 5 | import { version } from '../package.json' 6 | import { getSidebarObject } from './sidebar-gen' 7 | import { Advanced, BuiltIn, Guides, Resources } from './pages' 8 | import Customizations from './customizations' 9 | 10 | const slidebars: DefaultTheme.SidebarItem[] = [ 11 | { 12 | text: '指南', 13 | items: Guides, 14 | }, 15 | { 16 | text: '进阶', 17 | items: Advanced, 18 | }, 19 | { 20 | text: '定制', 21 | items: Customizations, 22 | }, 23 | { 24 | text: '内置', 25 | items: BuiltIn, 26 | }, 27 | { 28 | text: '资源', 29 | items: Resources, 30 | }, 31 | ] 32 | 33 | export default defineConfig({ 34 | title: 'Slidev', 35 | description: '为开发者打造的演示文稿工具', 36 | head: [ 37 | ['link', { rel: 'icon', type: 'image/png', href: '/favicon.png' }], 38 | ['meta', { name: 'author', content: 'Anthony Fu' }], 39 | ['meta', { property: 'og:title', content: 'Slidev 中文文档' }], 40 | ['meta', { property: 'og:image', content: 'https://sli.dev/og-image.png' }], 41 | ['meta', { property: 'og:description', content: '为开发者打造的演示文稿工具' }], 42 | ['meta', { name: 'twitter:card', content: 'summary_large_image' }], 43 | ['meta', { name: 'twitter:creator', content: '@slidevjs' }], 44 | ['meta', { name: 'twitter:image', content: 'https://sli.dev/og-image.png' }], 45 | ['link', { rel: 'dns-prefetch', href: 'https://fonts.gstatic.com' }], 46 | ['link', { rel: 'preconnect', crossorigin: 'anonymous', href: 'https://fonts.gstatic.com' }], 47 | ['link', { href: 'https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@200;400;500&family=Inter:wght@200;400;500;600', rel: 'stylesheet' }], 48 | ], 49 | markdown: { 50 | theme: { 51 | light: 'vitesse-light', 52 | dark: 'vitesse-dark', 53 | }, 54 | async shikiSetup(shiki) { 55 | await shiki.loadLanguage( 56 | 'html', 57 | 'xml', 58 | 'vue', 59 | 'markdown', 60 | 'mermaid', 61 | 'latex', 62 | ) 63 | }, 64 | codeTransformers: [ 65 | transformerTwoslash({ 66 | twoslashOptions: { 67 | // The @slidev/* installed in docs package are very old and should only be used in the homepage demo 68 | vfsRoot: fileURLToPath(import.meta.url), 69 | compilerOptions: { 70 | resolveJsonModule: true, 71 | }, 72 | }, 73 | }), 74 | ], 75 | }, 76 | cleanUrls: true, 77 | themeConfig: { 78 | logo: '/logo.svg', 79 | editLink: { 80 | pattern: 'https://github.com/slidevjs/docs-cn/edit/main/:path', 81 | text: '改进翻译', 82 | }, 83 | 84 | outlineTitle: '本页目录', 85 | 86 | search: { 87 | provider: 'local', 88 | }, 89 | 90 | nav: [ 91 | { 92 | text: '📖 指南', 93 | items: [ 94 | ...Guides, 95 | { 96 | text: '进阶', 97 | items: Advanced, 98 | }, 99 | ], 100 | }, 101 | { 102 | text: '✨ 功能', 103 | link: '/features/', 104 | }, 105 | { 106 | text: '参考', 107 | items: [ 108 | { 109 | text: '内置', 110 | items: BuiltIn, 111 | }, 112 | { 113 | text: '定制', 114 | items: Customizations, 115 | }, 116 | ], 117 | }, 118 | { 119 | text: '资源', 120 | items: Resources, 121 | }, 122 | ], 123 | 124 | socialLinks: [ 125 | { icon: 'github', link: 'https://github.com/slidevjs/slidev' }, 126 | { icon: 'twitter', link: 'https://twitter.com/slidevjs' }, 127 | { icon: 'discord', link: 'https://chat.sli.dev' }, 128 | ], 129 | 130 | sidebar: { 131 | '/guide/': slidebars, 132 | '/themes/': slidebars, 133 | '/addons/': slidebars, 134 | '/custom/': slidebars, 135 | '/builtin/': slidebars, 136 | '/resources/': slidebars, 137 | ...await getSidebarObject(), 138 | '/features/': [], 139 | '/': slidebars, 140 | }, 141 | 142 | footer: { 143 | message: 'Released under the MIT License.', 144 | copyright: 'Copyright © 2020-2024 Anthony Fu.', 145 | }, 146 | }, 147 | 148 | locales: { 149 | root: { 150 | label: `简体中文 (v${version})`, 151 | }, 152 | zh: { 153 | label: 'English', 154 | link: 'https://sli.dev/', 155 | }, 156 | }, 157 | }) 158 | -------------------------------------------------------------------------------- /custom/index.md: -------------------------------------------------------------------------------- 1 | # 自定义 2 | 3 | 在 Slidev 中,从样式到工具都是完全可以自定义的。你可以对 [Vite](/custom/config-vite)、[UnoCSS](/custom/config-unocss)、[Monaco](/custom/config-monaco) 等工具进行自定义配置。 4 | 5 | ## Headmatter {#headmatter} 6 | 7 | **第一张**幻灯片的 Frontmatter 也叫 Headmatter,在此处可以配置整个幻灯片。以下是各选项及其的默认值: 8 | 9 | 10 | ```yaml 11 | --- 12 | # 主题 id 或 主题包名称 13 | # 了解更多:https://cn.sli.dev/guide/theme-addon#use-theme 14 | theme: default 15 | # 附加组件, 一个可以含包名或本地路径的数组。 16 | # 了解更多: https://cn.sli.dev/guide/theme-addon#use-addon 17 | addons: [] 18 | # 幻灯片的总标题,如果没有指定,那么将以第一张拥有标题的幻灯片的标题作为总标题。 19 | title: Slidev 20 | # 网页的标题模板,`%s` 会被页面的标题替换。 21 | titleTemplate: '%s - Slidev' 22 | # 幻灯片信息,可以是一个 markdown 字符串。 23 | info: false 24 | # 导出的 PDF 或 PPTX 文件中的作者字段。 25 | author: Your Name Here 26 | # 导出的 PDF 文件中的关键字,以逗号分割。 27 | keywords: keyword1,keyword2 28 | 29 | # 启用演讲者模式,可以是一个 boolean 值、'dev' 或 'build' 30 | presenter: true 31 | # 在单页(SPA)构建中启用 pdf 下载,也可以指定一个自定义 url 32 | download: false 33 | # 要导出文件的文件名称 34 | exportFilename: slidev-exported 35 | # 导出选项 36 | # 使用驼峰命名法的导出 CLI 选项 37 | # 了解更多: https://cn.sli.dev/guide/exporting 38 | export: 39 | format: pdf 40 | timeout: 30000 41 | dark: false 42 | withClicks: false 43 | withToc: false 44 | # 语法高亮设置,可以使用 'shiki' 或 'prism'(已弃用) 方案 45 | highlighter: shiki 46 | # 启用 twoslash, 可以是一个 boolean 值,'dev' 或 'build' 47 | twoslash: true 48 | # 在代码块中显示行号 49 | lineNumbers: false 50 | # 启用 monaco 编辑器,可以是一个 boolean 值,'dev' 或 'build' 51 | monaco: true 52 | # 从何处加载 monaco 的类型,可以是 'cdn','local' 或 ‘none’ 53 | monacoTypesSource: local 54 | # 指定额外的本地包以导入 monaco 类型 55 | monacoTypesAdditionalPackages: [] 56 | # 指定额外的本地模块作为 monaco 可运行的依赖项 57 | monacoRunAdditionalDeps: [] 58 | # 使用 vite-plugin-remote-assets 在本地下载远程资源,可以是一个 boolean 值,'dev' 或者 'build' 59 | remoteAssets: false 60 | # 控制幻灯片中的文本是否可以被选择 61 | selectable: true 62 | # 启用幻灯片录制,可以是一个 boolean 值,'dev' 或者 'build' 63 | record: dev 64 | # 启用 Slidev 的前后文菜单,可以是一个 boolean 值,'dev' 或者 'build' 65 | contextMenu: true 66 | # 防止休眠,可以是一个 boolean 值,'dev' 或者 'build' 67 | wakeLock: true 68 | 69 | # 幻灯片的配色方案,可以使用 'auto','light' 或者 'dark' 70 | colorSchema: auto 71 | # vue-router 模式,可以使用 'history' 或 'hash' 模式 72 | routerMode: history 73 | # 幻灯片的长宽比 74 | aspectRatio: 16/9 75 | # canvas 的真实宽度,单位为 px 76 | canvasWidth: 980 77 | # 用于主题定制,会将属性 `x` 注入根样式 `--slidev-theme-x` 78 | themeConfig: 79 | primary: '#5d8392' 80 | 81 | # favicon 可以是本地文件路径,也可以是一个 URL 82 | favicon: 'https://cdn.jsdelivr.net/gh/slidevjs/slidev/assets/favicon.png' 83 | # 用于渲染图表的 PlantUML 服务器的 URL 84 | # 了解更多: https://cn.sli.dev/features/plantuml.html 85 | plantUmlServer: https://www.plantuml.com/plantuml 86 | # 字体将从 Google 字体自动导入 87 | # 了解更多: https://cn.sli.dev/custom/config-fonts 88 | fonts: 89 | sans: Roboto 90 | serif: Roboto Slab 91 | mono: Fira Code 92 | 93 | # 为所有幻灯片添加默认的 frontmatter 94 | defaults: 95 | layout: default 96 | # ... 97 | 98 | # 绘制选项 99 | # 了解更多:https://cn.sli.dev/features/drawing 100 | drawings: 101 | enabled: true 102 | persist: false 103 | presenterOnly: false 104 | syncAll: true 105 | 106 | # HTML 标签属性 107 | htmlAttrs: 108 | dir: ltr 109 | lang: en 110 | --- 111 | ``` 112 | 113 | 你可以从 [类型定义](https://github.com/slidevjs/slidev/blob/main/packages/types/src/config.ts) 获取到更多的配置信息。 114 | 115 | ## Frontmatter {#frontmatter} 116 | 117 | 此外,每张幻灯片的 Frontmatter 中,可以配置该幻灯片的特定属性。以下是各选项及其的默认值: 118 | 119 | ```yaml 120 | --- 121 | # 自定义点击计数 122 | # 了解更多: https://cn.sli.dev/guide/animations#custom-total-clicks-count 123 | clicks: 0 124 | # 自定义初始点击次数 125 | clicksStart: 0 126 | # 完全禁用和隐藏幻灯片 127 | disabled: false 128 | # 作用参考 `disabled` 配置。 129 | hide: false 130 | # 为 `` 组件隐藏幻灯片 131 | hideInToc: false 132 | # 定义应用于幻灯片的布局组件 133 | layout: <"cover" if the slide is the first slide, otherwise "default"> 134 | # 仅当同时声明了 `title` 配置时,为 `` 和 `` 提供组件级的标题覆盖 135 | level: 1 136 | # 预加载下一张幻灯片 137 | preload: true 138 | # 创建一个路由别名,可用于 URL 或 `` 组件 139 | routeAlias: undefined # 或 string 140 | # 引入一个 Markdown 文件 141 | # 了解更多: https://cn.sli.dev/guide/syntax.html#importing-slides 142 | src: undefined # 或 string 143 | # 仅当同时声明了 `level` 配置时,覆盖 `` 和 `` 组件的标题 144 | title: undefined # 或 string 145 | # 定义幻灯片与下一张幻灯片之间的过渡 146 | # 了解更多: https://cn.sli.dev/guide/animations.html#slide-transitions 147 | transition: undefined # 或 string | TransitionProps 148 | # 自定义缩放比例 149 | # 适用于内容较多的幻灯片 150 | zoom: 1 151 | # 用于可拖动元素的位置 152 | # 了解更多: https://cn.sli.dev/features/draggable.html 153 | dragPos: {} # 类型: Record 154 | --- 155 | ``` 156 | 157 | ## 目录结构 158 | 159 | Slidev 使用特定的目录结构来减少配置的复杂度,并使功能扩展更加的灵活和直观。 160 | 161 | 具体请参考 [目录结构](./directory-structure) 章节。 162 | 163 | ## 配置工具 164 | 165 | 169 | 170 |
  • 171 | 172 | {{ c.text }} 173 | 174 |
  • 175 | -------------------------------------------------------------------------------- /guide/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # 快速上手 {#getting-started} 6 | 7 | Slidev (slide + dev, **/slaɪdɪv/**) 是一个为开发者设计的基于 Web 的幻灯片制作工具。它帮助您以 Markdown 的形式专注于编写幻灯片的内容,并制作出具有交互式演示功能的、高度可自定义的幻灯片。 8 | 9 | ::: tip 10 | 11 | 你可以在 部分了解更多关于本项目的设计初衷。 12 | 13 | ::: 14 | 15 | 32 | 33 | 34 | 35 | ## 创建幻灯片 {#create-slides} 36 | 37 | ### 在浏览器中创建 {#try-it-online} 38 | 39 | 通过 StackBlitz 在浏览器中创建幻灯片: [sli.dev/new](https://sli.dev/new) 40 | 41 | ### 在本地创建 {#create-locally} 42 | 43 | > 需要先安装 [Node.js](https://nodejs.org) >= 18.0 44 | 45 | 在终端运行以下命令来创建一个新的 Slidev 项目: 46 | 47 | ::: code-group 48 | 49 | ```bash [npm] 50 | npm init slidev@latest 51 | ``` 52 | 53 | ```bash [pnpm] 54 | pnpm create slidev 55 | ``` 56 | 57 | ```bash [yarn] 58 | yarn create slidev 59 | ``` 60 | 61 | ::: 62 | 63 | 根据指引,输入项目名称并按照提示完成项目创建。幻灯片内容在 `slides.md` 文件中,初始内容包含了 Slidev 的大部分功能的演示。关于幻灯片 Markdown 语法的更多信息,请查看 。 64 | 65 | :::: details 单文件模式 (不推荐) 66 | 67 | 如果你不想创建一个 Node.js 包来管理你的幻灯片,可以选择全局安装 Slidev CLI: 68 | 69 | ::: code-group 70 | 71 | ```bash [npm] 72 | npm i -g @slidev/cli 73 | ``` 74 | 75 | ```bash [pnpm] 76 | pnpm i -g @slidev/cli 77 | ``` 78 | 79 | ```bash [yarn] 80 | yarn global add @slidev/cli 81 | ``` 82 | 83 | ::: 84 | 85 | 然后,你可以通过以下命令创建并启动幻灯片: 86 | 87 | ```bash 88 | slidev slides.md 89 | ``` 90 | 91 | :::: 92 | 93 | ## 基本命令 {#basic-commands} 94 | 95 | 以下是 Slidev 的一些常用命令: 96 | 97 | - `slidev` - 启动开发服务器。细节请参见 [dev 命令](../builtin/cli#dev) 98 | - `slidev export` - 将幻灯片导出为 PDF、PPTX 或 PNG 文件。细节请参见 99 | - `slidev build` - 将幻灯片构建为静态网页。细节请参见 100 | - `slidev format` - 将幻灯片格式化。细节请参见 [format 命令](../builtin/cli#format) 101 | - `slidev --help` - 显示帮助信息 102 | 103 | 你可以将这些命令添加到你的 `package.json` 的 `scripts` 字段中,来更方便地运行它们(如果幻灯片项目是通过 `npm init slidev` 创建的,则可以跳过这一步): 104 | 105 | ```json 106 | { 107 | "scripts": { 108 | "dev": "slidev --open", 109 | "build": "slidev build", 110 | "export": "slidev export" 111 | } 112 | } 113 | ``` 114 | 115 | 这样,你就可以通过 `npm run dev`、`npm run build` 和 `npm run export` 来运行这些命令了。 116 | 117 | 关于 CLI 的更多信息,请查看 [CLI 指南](../builtin/cli)。 118 | 119 | ## 配置编辑器 {#editor} 120 | 121 | 因为 Slidev 使用 Markdown 作为幻灯片的基本格式,你可以使用任何你喜欢的编辑器来开发你的幻灯片。我们也提供了一些工具来帮助你更方便地开发幻灯片: 122 | 123 | 124 | 125 | 126 | 127 | ## 加入社区 {#join-the-community} 128 | 129 | 欢迎加入我们的 [Discord 服务器](https://chat.sli.dev/),获取帮助、分享你的幻灯片,或者讨论关于 Slidev 的任何事情。 130 | 131 | 如果你遇到了疑似 bug 的问题,欢迎在 [GitHub](https://github.com/slidevjs/slidev/issues/new/choose) 上开一个 issue。 132 | 133 | ## 技术栈 {#tech-stack} 134 | 135 | Slidev 基于以下工具和技术构建: 136 | 137 | - [Vite](https://vitejs.dev) - 一款极速响应的下一代的前端工具链 138 | - [Vue 3](https://v3.vuejs.org/) powered [Markdown](https://daringfireball.net/projects/markdown/syntax) - 用于编写幻灯片内容 139 | - [UnoCSS](https://github.com/unocss/unocss) - 帮助快速构建幻灯片样式 140 | - [Shiki](https://github.com/shikijs/shiki), [Monaco Editor](https://github.com/Microsoft/monaco-editor) - 为在幻灯片中嵌入代码提供一流支持 141 | - [RecordRTC](https://recordrtc.org) - 内置的录制工具和摄像头视图 142 | - [VueUse](https://vueuse.org) 系列 - [`@vueuse/core`](https://github.com/vueuse/vueuse), [`@vueuse/head`](https://github.com/vueuse/head), [`@vueuse/motion`](https://github.com/vueuse/motion), 等等 143 | - [Iconify](https://iconify.design/) - 用图标集丰富你的幻灯片 144 | - [Drauu](https://github.com/antfu/drauu) - 用于在幻灯片上绘图和批注 145 | - [KaTeX](https://katex.org/) - 用于渲染 LaTeX 数学公式 146 | - [Mermaid](https://mermaid-js.github.io/mermaid) - 基于文本的图表绘制工具 147 | -------------------------------------------------------------------------------- /guide/hosting.md: -------------------------------------------------------------------------------- 1 | --- 2 | outline: deep 3 | --- 4 | 5 | # 编译和部署 6 | 7 | Slidev 被设计为在编辑或展示幻灯片时作为 Web 服务器运行。然而,在展示之后,你可能希望与他人分享你的**交互式**幻灯片。本指南将向你展示如何构建和部署你的幻灯片。 8 | 9 | ## 编译为静态网页 {#spa} 10 | 11 | 你可以通过以下命令将幻灯片构建为静态的 [单页应用 (SPA)](https://developer.mozilla.org/en-US/docs/Glossary/SPA): 12 | 13 | ```bash 14 | $ slidev build 15 | ``` 16 | 17 | 默认情况下,生成的文件会被放在 `dist` 文件夹中。你可以通过运行 `npx vite preview` 或任何其他静态服务器来测试你的幻灯片的构建版本。 18 | 19 | ### 基础路径 {#base} 20 | 21 | 若要将你的幻灯片部署在子目录下,你需要传递 `--base` 选项。`--base` 路径**必须以斜杠 `/` 开头和结尾**。例如: 22 | 23 | ```bash 24 | $ slidev build --base /talks/my-cool-talk/ 25 | ``` 26 | 27 | 参阅 [Vite 文档](https://cn.vitejs.dev/guide/build.html#public-base-path) 了解更多细节。 28 | 29 | ### 输出目录 {#output-directory} 30 | 31 | 你可以通过 `--out` 选项更改输出目录: 32 | 33 | ```bash 34 | $ slidev build --out my-build-folder 35 | ``` 36 | 37 | ### 多个幻灯片 {#multiple-slides} 38 | 39 | 你可以通过传递多个 Markdown 文件作为参数一次性构建多个幻灯片: 40 | 41 | ```bash 42 | $ slidev build slides1.md slides2.md 43 | ``` 44 | 45 | 或者,如果你的 shell 支持,你可以使用通配符: 46 | 47 | ```bash 48 | $ slidev build *.md 49 | ``` 50 | 51 | 在上例中,每个输入文件将在输出目录中生成一个包含构建的文件夹。 52 | 53 | ### 例子 {#examples} 54 | 55 | 以下是一些导出的 SPA 的例子: 56 | 57 | - [Demo Slides](https://sli.dev/demo/starter) 58 | - [Composable Vue](https://talks.antfu.me/2021/composable-vue) by [Anthony Fu](https://github.com/antfu) 59 | - 更多请查阅 [案例展示](../resources/showcases) 60 | 61 | ### 选项 {#options} 62 | 63 | 64 | 65 | 66 | ## 静态部署 {#hosting} 67 | 68 | 我们推荐使用 `npm init slidev@latest` 来初始化你的项目,它包含了一些常用的部署配置文件。 69 | 70 | ### GitHub Pages {#github-pages} 71 | 72 | 要通过 GitHub Actions 在 [GitHub Pages](https://pages.github.com/) 上部署你的幻灯片,请按照以下步骤操作: 73 | 74 | 1. 在你的仓库中上传所有项目文件(例如命名为 `name_of_repo`)。 75 | 2. 创建 `.github/workflows/deploy.yml` 文件,内容如下,以通过 GitHub Actions 将你的幻灯片部署到 GitHub Pages。 76 | 77 | ::: details deploy.yml 78 | 79 | ```yaml 80 | name: Deploy pages 81 | 82 | on: 83 | workflow_dispatch: 84 | push: 85 | branches: [main] 86 | 87 | permissions: 88 | contents: read 89 | pages: write 90 | id-token: write 91 | 92 | concurrency: 93 | group: pages 94 | cancel-in-progress: false 95 | 96 | jobs: 97 | build: 98 | runs-on: ubuntu-latest 99 | 100 | steps: 101 | - uses: actions/checkout@v4 102 | 103 | - uses: actions/setup-node@v4 104 | with: 105 | node-version: 'lts/*' 106 | 107 | - name: Setup @antfu/ni 108 | run: npm i -g @antfu/ni 109 | 110 | - name: Install dependencies 111 | run: nci 112 | 113 | - name: Build 114 | run: nr build --base /${{github.event.repository.name}}/ 115 | 116 | - name: Setup Pages 117 | uses: actions/configure-pages@v4 118 | 119 | - uses: actions/upload-pages-artifact@v3 120 | with: 121 | path: dist 122 | 123 | deploy: 124 | environment: 125 | name: github-pages 126 | url: ${{ steps.deployment.outputs.page_url }} 127 | needs: build 128 | runs-on: ubuntu-latest 129 | name: Deploy 130 | steps: 131 | - name: Deploy to GitHub Pages 132 | id: deployment 133 | uses: actions/deploy-pages@v4 134 | ``` 135 | 136 | ::: 137 | 138 | 3. 在你的仓库中,转到 `Settings` > `Pages`。在 `Build and deployment` 下,选择 `GitHub Actions`。 139 | 4. 最后,在工作流执行后,幻灯片的链接应该会出现在 `Settings` > `Pages` 下。 140 | 141 | ### Netlify 142 | 143 | 创建项目根目录下的 `netlify.toml` 文件,内容如下: 144 | 145 | ::: details netlify.toml 146 | 147 | ```toml 148 | [build] 149 | publish = 'dist' 150 | command = 'npm run build' 151 | 152 | [build.environment] 153 | NODE_VERSION = '20' 154 | 155 | [[redirects]] 156 | from = '/*' 157 | to = '/index.html' 158 | status = 200 159 | ``` 160 | 161 | ::: 162 | 163 | 然后,你可以在 [Netlify dashboard](https://netlify.com/) 中创建一个新站点,并将仓库与之关联。 164 | 165 | ### Vercel 166 | 167 | 创建项目根目录下的 `vercel.json` 文件,内容如下: 168 | 169 | ::: details vercel.json 170 | 171 | ```json 172 | { 173 | "rewrites": [ 174 | { "source": "/(.*)", "destination": "/index.html" } 175 | ] 176 | } 177 | ``` 178 | 179 | ::: 180 | 181 | 然后,你可以在 [Vercel dashboard](https://vercel.com/) 中创建一个新站点,并将仓库与之关联。 182 | 183 | ### 在 Docker 上部署 {#docker} 184 | 185 | 如果你需要一个快速的容器运行幻灯片的方式,你可以使用由 [tangramor](https://github.com/tangramor) 维护的预构建 [Docker Image](https://hub.docker.com/r/tangramor/slidev),或者自己构建一个。 186 | 187 | ::: details 使用 Docker Image 188 | 189 | 只需在你的工作目录中运行以下命令: 190 | 191 | ```bash 192 | docker run --name slidev --rm -it \ 193 | --user node \ 194 | -v ${PWD}:/slidev \ 195 | -p 3030:3030 \ 196 | -e NPM_MIRROR="https://registry.npmmirror.com" \ 197 | tangramor/slidev:latest 198 | ``` 199 | 200 | **_Note_**: 你可以使用 `NPM_MIRROR` 来指定一个 npm 镜像以加快安装过程。 201 | 202 | 如果你的工作目录为空,它将在你的工作目录下生成一个模板 `slides.md` 和其他相关文件,并在端口 `3030` 上启动服务器。然后,你可以从 `http://localhost:3030/` 访问你的幻灯片。 203 | 204 | 若要用你的幻灯片创建一个 Docker Image,你可以使用以下 Dockerfile: 205 | 206 | ```Dockerfile 207 | FROM tangramor/slidev:latest 208 | 209 | ADD . /slidev 210 | ``` 211 | 212 | 创建 Docker Image:`docker build -t myslides .` 213 | 214 | 运行容器:`docker run --name myslides --rm --user node -p 3030:3030 myslides` 215 | 216 | 然后,你可以从 `http://localhost:3030/` 访问你的幻灯片。 217 | 218 | ::: 219 | -------------------------------------------------------------------------------- /.vitepress/theme/styles/vars.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Customize default theme styling by overriding CSS variables: 3 | * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css 4 | */ 5 | 6 | /** 7 | * Colors 8 | * 9 | * Each colors have exact same color scale system with 3 levels of solid 10 | * colors with different brightness, and 1 soft color. 11 | * 12 | * - `XXX-1`: The most solid color used mainly for colored text. It must 13 | * satisfy the contrast ratio against when used on top of `XXX-soft`. 14 | * 15 | * - `XXX-2`: The color used mainly for hover state of the button. 16 | * 17 | * - `XXX-3`: The color for solid background, such as bg color of the button. 18 | * It must satisfy the contrast ratio with pure white (#ffffff) text on 19 | * top of it. 20 | * 21 | * - `XXX-soft`: The color used for subtle background such as custom container 22 | * or badges. It must satisfy the contrast ratio when putting `XXX-1` colors 23 | * on top of it. 24 | * 25 | * The soft color must be semi transparent alpha channel. This is crucial 26 | * because it allows adding multiple "soft" colors on top of each other 27 | * to create a accent, such as when having inline code block inside 28 | * custom containers. 29 | * 30 | * - `default`: The color used purely for subtle indication without any 31 | * special meanings attched to it such as bg color for menu hover state. 32 | * 33 | * - `brand`: Used for primary brand colors, such as link text, button with 34 | * brand theme, etc. 35 | * 36 | * - `tip`: Used to indicate useful information. The default theme uses the 37 | * brand color for this by default. 38 | * 39 | * - `warning`: Used to indicate warning to the users. Used in custom 40 | * container, badges, etc. 41 | * 42 | * - `danger`: Used to show error, or dangerous message to the users. Used 43 | * in custom container, badges, etc. 44 | * -------------------------------------------------------------------------- */ 45 | 46 | :root { 47 | --vp-c-brand-1: #3ab9d4; 48 | --vp-c-brand-2: #60c4db; 49 | --vp-c-brand-3: #6fcce1; 50 | --vp-c-brand-soft: #3ab9d450; 51 | --vp-c-bg-alt: #f9f9f9; 52 | 53 | --vp-font-family-mono: theme('fontFamily.mono'); 54 | } 55 | 56 | .dark { 57 | --vp-c-brand-1: #6fcce1; 58 | --vp-c-brand-2: #60c4db; 59 | --vp-c-brand-3: #3ab9d4; 60 | --vp-c-brand-soft: #3ab9d450; 61 | --vp-c-bg-alt: #18181b; 62 | --vp-c-gutter: #8883; 63 | } 64 | 65 | :root { 66 | --vp-c-default-1: var(--vp-c-gray-1); 67 | --vp-c-default-2: var(--vp-c-gray-2); 68 | --vp-c-default-3: var(--vp-c-gray-3); 69 | --vp-c-default-soft: var(--vp-c-gray-soft); 70 | 71 | --vp-c-tip-1: var(--vp-c-brand-1); 72 | --vp-c-tip-2: var(--vp-c-brand-2); 73 | --vp-c-tip-3: var(--vp-c-brand-3); 74 | --vp-c-tip-soft: var(--vp-c-brand-soft); 75 | } 76 | 77 | :root { 78 | -vp-c-text-1: rgba(42, 40, 47); 79 | -vp-c-text-2: rgba(42, 40, 47, 0.78); 80 | -vp-c-text-3: rgba(42, 40, 47, 0.56); 81 | --black-text-1: rgba(42, 40, 47); 82 | } 83 | 84 | .dark { 85 | --vp-c-text-1: rgba(255, 255, 245, 0.86); 86 | --vp-c-text-2: rgba(235, 235, 245, 0.6); 87 | --vp-c-text-3: rgba(235, 235, 245, 0.38); 88 | } 89 | 90 | /** 91 | * Component: Button 92 | * -------------------------------------------------------------------------- */ 93 | 94 | :root { 95 | --vp-button-brand-border: transparent; 96 | --vp-button-brand-text: var(--vp-c-white); 97 | --vp-button-brand-bg: var(--vp-c-brand-1); 98 | --vp-button-brand-hover-border: transparent; 99 | --vp-button-brand-hover-text: var(--vp-c-white); 100 | --vp-button-brand-hover-bg: var(--vp-c-brand-2); 101 | --vp-button-brand-active-border: transparent; 102 | --vp-button-brand-active-text: var(--vp-c-white); 103 | --vp-button-brand-active-bg: var(--vp-c-brand-1); 104 | } 105 | 106 | .dark { 107 | --vp-button-brand-text: var(--black-text-1); 108 | --vp-button-brand-bg: var(--vp-c-brand-2); 109 | --vp-button-brand-hover-text: var(--black-text-1); 110 | --vp-button-brand-hover-bg: var(--vp-c-brand-1); 111 | --vp-button-brand-active-text: var(--black-text-1); 112 | --vp-button-brand-active-bg: var(--vp-c-brand-3); 113 | } 114 | 115 | /** 116 | * Component: Home 117 | * -------------------------------------------------------------------------- */ 118 | 119 | :root { 120 | --vp-home-hero-name-color: var(--vp-c-brand-1); 121 | } 122 | 123 | @media (min-width: 640px) { 124 | :root { 125 | --vp-home-hero-image-filter: blur(56px); 126 | } 127 | } 128 | 129 | @media (min-width: 960px) { 130 | :root { 131 | --vp-home-hero-image-filter: blur(72px); 132 | } 133 | } 134 | 135 | /** 136 | * Component: Custom Block 137 | * -------------------------------------------------------------------------- */ 138 | 139 | :root { 140 | --vp-custom-block-tip-border: transparent; 141 | --vp-custom-block-tip-text: var(--vp-c-text-1); 142 | --vp-custom-block-tip-bg: var(--vp-c-brand-soft); 143 | --vp-custom-block-tip-code-bg: var(--vp-c-brand-soft); 144 | } 145 | 146 | /** 147 | * Component: Algolia 148 | * -------------------------------------------------------------------------- */ 149 | 150 | .DocSearch { 151 | --docsearch-primary-color: var(--vp-c-brand-1) !important; 152 | } 153 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
    2 |

    3 | 4 | Slidev 5 | 6 |

    7 | 8 |

    9 | 为开发者打造的演示文稿工具 🧑‍💻👩‍💻👨‍💻 10 |

    11 | 12 |

    13 | NPM version 14 | NPM Downloads 15 | Docs & Demos 16 | Themes 17 |
    18 | GitHub stars 19 |

    20 | 21 | ## Slidev 中文文档 22 | 23 | - 📝 [**Markdown 支持**](https://cn.sli.dev/guide/syntax.html) —— 使用你最喜欢的编辑器和工作流编写 Markdown 文件 24 | - 🧑‍💻 [**对开发者友好**](https://cn.sli.dev/guide/syntax.html#code-blocks) —— 内置代码高亮、实时编码等功能 25 | - 🎨 [**可定制主题**](https://cn.sli.dev/themes/gallery.html) —— 以 npm 包的形式共享、使用主题 26 | - 🌈 [**灵活样式**](https://cn.sli.dev/guide/syntax.html#embedded-styles) —— 使用 [Windi CSS](https://windicss.org/) 按需使用的实用类和易用的内嵌样式表 27 | - 🤹 [**交互**](https://cn.sli.dev/custom/directory-structure.html#components) —— 无缝嵌入 Vue 组件 28 | - 🎙 [**演示者模式**](https://cn.sli.dev/guide/presenter-mode.html) —— 可以使用另一个窗口,甚至是你的手机来控制幻灯片 29 | - 🧮 [**LaTeX 支持**](https://cn.sli.dev/guide/syntax.html#latex) —— 内置了对 LaTeX 数学公示的支持 30 | - 📰 [**图表支持**](https://cn.sli.dev/guide/syntax.html#diagrams) —— 使用文本描述语言创建图表 31 | - 🌟 [**图标**](https://cn.sli.dev/guide/syntax.html#icons) —— 能够直接从任意图标库中获取图标 32 | - 💻 [**编辑器**](https://cn.sli.dev/guide/editors.html) —— 集成的编辑器,或者使用 [VS Code 扩展](https://github.com/slidevjs/slidev-vscode) 33 | - 🎥 [**录制**](https://cn.sli.dev/guide/recording.html) —— 内置录制功能和摄像头视图 34 | - 📤 [**跨平台**](https://cn.sli.dev/guide/exporting.html) —— 能够导出 PDF、PNG 文件,甚至是一个可以托管的单页应用 35 | - ⚡️ [**快速**](https://vitejs.dev) —— 基于 [Vite](https://vitejs.dev) 的即时重载 36 | - 🛠 [**可配置**](https://cn.sli.dev/custom/config-vite.html) —— 支持使用 Vite 插件、Vue 组件以及任何的 npm 包 37 | 38 | ### 📨 与官网文档同步 39 | 40 | 目前 Slidev 中文文档翻译已全部完成。 41 | 42 | **同步原理**:每天,[主仓库](https://github.com/slidevjs/slidev)的 `docs` 目录会被提取到本仓库的 `upstream` 分支。本仓库的 `sync` 分支会在需要时从 `main` 和 `upstream` 分支合并,并在完成翻译后发起 PR 到主仓库的 `main` 分支。 43 | 44 | ### 📝 参与贡献 45 | 46 | 感谢您的参与!若要修正翻译错误,请向 main 分支提交 PR;若要帮助翻译新增内容,请向 sync 分支提交 PR;若英文原版即有需要修改之处,请向[主仓库](https://github.com/slidevjs/slidev)提交 PR。 47 | 48 | 若需要本地预览网站效果,可执行如下命令: 49 | 50 | ```bash 51 | # 全局安装 pnpm 52 | $ npm i -g pnpm 53 | 54 | # 安装依赖,使用 pnpm 55 | $ pnpm i 56 | # 启动文档 57 | $ pnpm run dev 58 | ``` 59 | 60 | 接着访问提示的网址(一般为 `http://localhost:5173/`)即可。 61 | 62 | 或者安装 [VSCode 的 Vite 插件](https://marketplace.visualstudio.com/items?itemName=antfu.vite) 快速启动开发服务器。 63 | 64 | ### 贡献者 65 | 66 | 感谢各位贡献者的付出(以下排名不分先后): 67 | 68 | 新版文档: 69 | 70 | | _Kerman | wemsx | XiaoDong | 诺墨 | 71 | | :-: | :-: | :-: | :-: | 72 | | [![](https://avatars.githubusercontent.com/u/63178754?s=120&v=4)](https://github.com/kermanx) | [![](https://avatars.githubusercontent.com/u/84974015?s=120&v=4)](https://github.com/wemsx) | [![](https://avatars.githubusercontent.com/u/84657208?s=120&v=4)](https://github.com/xiaodong2008) | [![](https://avatars.githubusercontent.com/u/6902432?s=120&v=4)](https://github.com/normal-coder) | 73 | 74 | 初版文档: 75 | 76 | | Anthony Fu | QiChang Li | 清秋 | Chuck | Songhn | ArcherGu | 77 | | :-----: | :-------: | :-----: | :-----: | :-----: | :-----: | 78 | | [![antfu](https://avatars.githubusercontent.com/u/11247099?s=120&v=4)](https://github.com/antfu) | [![QC-L](https://avatars.githubusercontent.com/u/13861040?s=120&v=4)](https://github.com/QC-L) | [![Ivocin](https://avatars.githubusercontent.com/u/16836801?s=120&v=4)](https://github.com/Ivocin) | [![ChuanfengZhang](https://avatars.githubusercontent.com/u/18238800?s=120&v=4)](https://github.com/ChuanfengZhang) | [![songhn233](https://avatars.githubusercontent.com/u/47357585?s=120&v=4)](https://github.com/songhn233) | [![ArcherGu](https://avatars.githubusercontent.com/u/34826812?s=120&v=4)](https://github.com/ArcherGu) | [![KimYang](https://avatars.githubusercontent.com/u/32960305?s=120&v=4)](https://github.com/KimYangOfCat)| 79 | | Jacob | Qiang | raintygao | 六个骨头 | Kim Yang | KnowsCount | 80 | | [![jacob-lcs](https://avatars.githubusercontent.com/u/40483898?s=120&v=4)](https://github.com/jacob-lcs) | [![iDestin](https://avatars.githubusercontent.com/u/36811055?s=120&v=4)](https://github.com/iDestin) | [](https://github.com/raintygao) | [![zrr1999](https://avatars.githubusercontent.com/u/46243324?s=120&v=4)](https://github.com/zrr1999) |[![KimYangOfCat](https://avatars.githubusercontent.com/u/32960305?s=120&v=4)](https://github.com/KimYangOfCat) |[![KnowsCount](https://avatars.githubusercontent.com/u/56480008?s=120&v=4)](https://github.com/KnowsCount) | 81 | | ZhengX | 82 | |[![Megrax](https://avatars.githubusercontent.com/u/56376387?s=120&v=4)](https://github.com/Megrax) | 83 | -------------------------------------------------------------------------------- /.vitepress/theme/components/Demo.vue: -------------------------------------------------------------------------------- 1 | 122 | 123 | 170 | 171 | 179 | -------------------------------------------------------------------------------- /components.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // @ts-nocheck 3 | // Generated by unplugin-vue-components 4 | // Read more: https://github.com/vuejs/core/pull/3399 5 | export {} 6 | 7 | /* prettier-ignore */ 8 | declare module 'vue' { 9 | export interface GlobalComponents { 10 | AddonGallery: typeof import('./.vitepress/theme/components/AddonGallery.vue')['default'] 11 | AddonInfo: typeof import('./.vitepress/theme/components/AddonInfo.vue')['default'] 12 | Arrow: typeof import('./node_modules/@slidev/client/builtin/Arrow.vue')['default'] 13 | AutoFitText: typeof import('./node_modules/@slidev/client/builtin/AutoFitText.vue')['default'] 14 | 'Carbon:chevronLeft': typeof import('~icons/carbon/chevron-left')['default'] 15 | 'Carbon:chevronRight': typeof import('~icons/carbon/chevron-right')['default'] 16 | 'Carbon:close': typeof import('~icons/carbon/close')['default'] 17 | 'Carbon:filterRemove': typeof import('~icons/carbon/filter-remove')['default'] 18 | 'Carbon:logoGithub': typeof import('~icons/carbon/logo-github')['default'] 19 | 'Carbon:logoTwitter': typeof import('~icons/carbon/logo-twitter')['default'] 20 | 'Carbon:presentationFile': typeof import('~icons/carbon/presentation-file')['default'] 21 | 'Carbon:reset': typeof import('~icons/carbon/reset')['default'] 22 | 'Carbon:search': typeof import('~icons/carbon/search')['default'] 23 | 'Carbon:tag': typeof import('~icons/carbon/tag')['default'] 24 | 'Carbon:video': typeof import('~icons/carbon/video')['default'] 25 | CarbonApps: typeof import('~icons/carbon/apps')['default'] 26 | CarbonArrowLeft: typeof import('~icons/carbon/arrow-left')['default'] 27 | CarbonArrowRight: typeof import('~icons/carbon/arrow-right')['default'] 28 | CarbonBadge: typeof import('~icons/carbon/badge')['default'] 29 | CarbonDownload: typeof import('~icons/carbon/download')['default'] 30 | CarbonEdit: typeof import('~icons/carbon/edit')['default'] 31 | CarbonInformation: typeof import('~icons/carbon/information')['default'] 32 | CarbonListBoxes: typeof import('~icons/carbon/list-boxes')['default'] 33 | CarbonMaximize: typeof import('~icons/carbon/maximize')['default'] 34 | CarbonMinimize: typeof import('~icons/carbon/minimize')['default'] 35 | CarbonMoon: typeof import('~icons/carbon/moon')['default'] 36 | CarbonPen: typeof import('~icons/carbon/pen')['default'] 37 | CarbonSettingsAdjust: typeof import('~icons/carbon/settings-adjust')['default'] 38 | CarbonSun: typeof import('~icons/carbon/sun')['default'] 39 | CarbonUserAvatar: typeof import('~icons/carbon/user-avatar')['default'] 40 | CarbonUserSpeaker: typeof import('~icons/carbon/user-speaker')['default'] 41 | CarbonVideo: typeof import('~icons/carbon/video')['default'] 42 | CodeBlockWrapper: typeof import('./node_modules/@slidev/client/builtin/CodeBlockWrapper.vue')['default'] 43 | CodiconAdd: typeof import('~icons/codicon/add')['default'] 44 | CodiconEye: typeof import('~icons/codicon/eye')['default'] 45 | CodiconLock: typeof import('~icons/codicon/lock')['default'] 46 | CodiconRunAll: typeof import('~icons/codicon/run-all')['default'] 47 | Demo: typeof import('./.vitepress/theme/components/Demo.vue')['default'] 48 | DemoEditor: typeof import('./.vitepress/theme/components/DemoEditor.vue')['default'] 49 | DemoSlide: typeof import('./.vitepress/theme/components/DemoSlide.vue')['default'] 50 | Environment: typeof import('./.vitepress/theme/components/Environment.vue')['default'] 51 | FeaturesAnimation: typeof import('./.vitepress/theme/components/FeaturesAnimation.vue')['default'] 52 | FeaturesAnimationInner: typeof import('./.vitepress/theme/components/FeaturesAnimationInner.vue')['default'] 53 | FeaturesOverview: typeof import('./.vitepress/theme/components/FeaturesOverview.vue')['default'] 54 | FeatureTag: typeof import('./.vitepress/theme/components/FeatureTag.vue')['default'] 55 | KaTexBlockWrapper: typeof import('./node_modules/@slidev/client/builtin/KaTexBlockWrapper.vue')['default'] 56 | LandingPage: typeof import('./.vitepress/theme/components/LandingPage.vue')['default'] 57 | Layout: typeof import('./.vitepress/theme/components/Layout.vue')['default'] 58 | LightOrDark: typeof import('./node_modules/@slidev/client/builtin/LightOrDark.vue')['default'] 59 | Link: typeof import('./node_modules/@slidev/client/builtin/Link.vue')['default'] 60 | LinkCard: typeof import('./.vitepress/theme/components/LinkCard.vue')['default'] 61 | LinkInline: typeof import('./.vitepress/theme/components/LinkInline.vue')['default'] 62 | LogosVue: typeof import('~icons/logos/vue')['default'] 63 | MdiAccountCircle: typeof import('~icons/mdi/account-circle')['default'] 64 | Mermaid: typeof import('./node_modules/@slidev/client/builtin/Mermaid.vue')['default'] 65 | Monaco: typeof import('./node_modules/@slidev/client/builtin/Monaco.vue')['default'] 66 | PlantUml: typeof import('./node_modules/@slidev/client/builtin/PlantUml.vue')['default'] 67 | PoweredBySlidev: typeof import('./node_modules/@slidev/client/builtin/PoweredBySlidev.vue')['default'] 68 | RenderWhen: typeof import('./node_modules/@slidev/client/builtin/RenderWhen.vue')['default'] 69 | RouterLink: typeof import('vue-router')['RouterLink'] 70 | RouterView: typeof import('vue-router')['RouterView'] 71 | SeeAlso: typeof import('./.vitepress/theme/components/SeeAlso.vue')['default'] 72 | ShikiMagicMove: typeof import('./node_modules/@slidev/client/builtin/ShikiMagicMove.vue')['default'] 73 | ShowCaseInfo: typeof import('./.vitepress/theme/components/ShowCaseInfo.vue')['default'] 74 | ShowCases: typeof import('./.vitepress/theme/components/ShowCases.vue')['default'] 75 | SimpleIconsGithub: typeof import('~icons/simple-icons/github')['default'] 76 | SimpleIconsNpm: typeof import('~icons/simple-icons/npm')['default'] 77 | SlideContainer: typeof import('./.vitepress/theme/components/SlideContainer.vue')['default'] 78 | SlideCurrentNo: typeof import('./node_modules/@slidev/client/builtin/SlideCurrentNo.vue')['default'] 79 | SlidesTotal: typeof import('./node_modules/@slidev/client/builtin/SlidesTotal.vue')['default'] 80 | SlidevVideo: typeof import('./node_modules/@slidev/client/builtin/SlidevVideo.vue')['default'] 81 | ThemeGallery: typeof import('./.vitepress/theme/components/ThemeGallery.vue')['default'] 82 | ThemeInfo: typeof import('./.vitepress/theme/components/ThemeInfo.vue')['default'] 83 | TheTweet: typeof import('./.vitepress/theme/components/TheTweet.vue')['default'] 84 | Toc: typeof import('./node_modules/@slidev/client/builtin/Toc.vue')['default'] 85 | TocList: typeof import('./node_modules/@slidev/client/builtin/TocList.vue')['default'] 86 | Transform: typeof import('./node_modules/@slidev/client/builtin/Transform.vue')['default'] 87 | Tweet: typeof import('./node_modules/@slidev/client/builtin/Tweet.vue')['default'] 88 | TwemojiCatWithTearsOfJoy: typeof import('~icons/twemoji/cat-with-tears-of-joy')['default'] 89 | UimRocket: typeof import('~icons/uim/rocket')['default'] 90 | VClickGap: typeof import('./node_modules/@slidev/client/builtin/VClickGap.vue')['default'] 91 | VDrag: typeof import('./node_modules/@slidev/client/builtin/VDrag.vue')['default'] 92 | VDragArrow: typeof import('./node_modules/@slidev/client/builtin/VDragArrow.vue')['default'] 93 | Youtube: typeof import('./node_modules/@slidev/client/builtin/Youtube.vue')['default'] 94 | } 95 | } 96 | --------------------------------------------------------------------------------