在 Markdown 中使用 Vue

浏览器 API 访问限制

因为 VitePress 应用在生成静态构建时是通过 Node.js 服务端渲染的,因此所有 Vue 的使用必须符合编写通用代码的要求。简而言之,要确保只在beforeMountmounted时访问浏览器/DOM 的接口。

如果你在使用或展示非 SSR 友好(比如包含自定义指令)的组件,你就可以使用ClientOnly将其包裹。

<ClientOnly>
  <NonSSRFriendlyComponent/>
</ClientOnly>

注意,这并不能解决一些组件或库在导入时就试图访问浏览器 API 的问题。 如果需要使用这样的组件或库,你需要在合适的生命周期钩子中动态导入:

<script>
export default {
  mounted() {
    import('./lib-that-access-window-on-import').then((module) => {
      // use code
    })
  }
}
</script>

如果你的模块export default一个 Vue 组件,那么你可以动态注册。

<template>
  <component v-if="dynamicComponent" :is="dynamicComponent"></component>
</template>

<script>
export default {
  data() {
    return {
      dynamicComponent: null
    }
  },

  mounted() {
    import('./lib-that-access-window-on-import').then((module) => {
      this.dynamicComponent = module.default
    })
  }
}
</script>

参考

模板语法

插值

每一个 Markdown 文件将首先被编译成 HTML,接着作为一个 Vue 组件传入 Vite 处理通道,这意味着你可以在文本中使用 Vue 风格的插值:

输入

{{ 1 + 1 }}

输出

2

指令

也可以使用指令:

输入

<span v-for="i in 3">{{ i }} </span>

输出

1 2 3 

访问站点及页面数据

编译后的组件可以访问 站点元数据和计算属性。例如:

输入

{{ $page }}

输出

{
  "path": "/using-vue.html",
  "title": "Using Vue in Markdown",
  "frontmatter": {}
}

Escaping

默认情况下,代码块(三个反引号包裹)将会被自动包裹在 v-pre 中。如果你想要在内联 (inline) 的代码块或者普通文本中显示原始的大括号或一些 Vue 特定的语法,你需要使用自定义容器 v-pre来包裹:

输入

::: v-pre
`{{ This will be displayed as-is }}`
:::

输出

{{ This will be displayed as-is }}

使用组件

当你需要更多灵活性时,VitePress 允许你使用你自己的 Vue 组件扩展你的创作工具箱。

在 Markdown 中引入组件

如果你的组件只是在少数几个地方使用,推荐你通过在你需要使用的文件中导入组件的方式来使用。

# Docs

This is a .md using a custom component

<CustomComponent />

## More docs

...

<script setup>
import CustomComponent from '../components/CustomComponent.vue'
</script>

在主题中注册全局组件

如果需要在文档的几个页面中使用这些组件,则可以在主题(或者作为扩展点儿 VitePress 主题的一部分)中全局注册这些组件。详情参见:Customization Guide

.vitepress/theme/index.js中, 因为enhanceApp 函数接受 Vueapp对象,所以你可以像普通 Vue 插件那样注册组件

import DefaultTheme from 'vitepress/theme'

export default {
  ...DefaultTheme,
  enhanceApp({ app }) {
    app.component('VueClickAwayExample', VueClickAwayExample)
  }
}

然后,你就能在 Markdown 文件的内容间使用组件。

# Vue Click Away

<VueClickAwayExample />

重要

确保自定义组件的名称包含连字符或是 PascalCase 格式。否者,它会被当成内联元素并包裹在<p>标签内,这将会导致 HTML 渲染紊乱, <p> 标签中不允许放置任何块级元素。

在标题中使用组件

你可以在标题中使用组件,但是注意下列语法中的不同:

Markdown输出的 HTML解析后的标题
 # text <Tag/> 
<h1>text <Tag/></h1>text
 # text `<Tag/>` 
<h1>text <code>&lt;Tag/&gt;</code></h1>text <Tag/>

<code> 包装的 HTML 将按原样显示,只有未被包装的 HTML 才会被 Vue 解析。

提示

输出的 HTML 由 markdown-it 完成。而解析后的标题由 VitePress 完成,用于侧边栏以及文档的标题。

使用 CSS 预处理器

VitePress 已经内建支持CSS 预处理器(支持.scss.sass.less.styl.stylus等文件)。这里不需要安装特定的 Vite 插件,只需要安装对应的预处理器自身。

# .scss and .sass
npm install -D sass

# .less
npm install -D less

# .styl and .stylus
npm install -D stylus

然后,你可以在 Markdown 和主题组件中像如下这样使用:

<style lang="sass">
.title
  font-size: 20px
</style>

脚本和样式提升

有时,你可能需要在当前页面使用一些 JavaScript 或 CSS。这些情况下,你可以在 Markdown 文件中根节点使用<script><style>标签。这些内容会被从编译后的 HTML 抽离出来,用在 Vue 单页组件中<script><style>块中。

内置组件

VitePress 提供内置 Vue 组件,如ClientOnlyOutboundLink,参见全局组件指南

更多参考: