VuePress 渲染 Mermaid 绘图

前言

本文将介绍 VuePress 如何渲染 Mermaid 绘图,适用于 VuePress 1.x 与 VuePress 2.x。

VuePress 1.x

VuePress 1.x 可以直接安装第三方插件 vuepress-plugin-mermaidjs 来渲染 Mermaid 绘图,插件的详细文档可看 这里

安装插件

安装插件时必须指定具体的版本号,否则默认会安装最新版本的插件,最新版本不兼容 VuePres 1.x。

1
$ npm install vuepress-plugin-mermaidjs@1.9.1 -D

配置插件

编辑 VuePress 1.x 的 .vuepress/config.js 配置文件,新增 mermaidjs 插件,如下所示:

1
2
3
4
5
module.exports = {
plugins: [
'vuepress-plugin-mermaidjs'
]
}

Markdown 渲染

语法说明

  • 第二种写法:使用代码块(推荐)

  • 第二种写法:使用 <mermaid> 标签

使用示例

1
2
3
4
5
6
7
<mermaid>
sequenceDiagram
Alice->John: Hello John, how are you?
loop every minute
John-->Alice: Great!
end
</mermaid>

VuePress 2.x

由于第三方插件 vuepress-plugin-mermaidjs 并没有适配最新版的 VuePress 2.x,因此需要手动配置 VuePress 2.x 来渲染 Mermaid 绘图。

安装依赖

  • 让 VuePress 2.x 支持 Mermaid
1
$ npm install mermaid -D
  • 让 VuePress 2.x 支持自定义组件
1
$ npm install @vuepress/plugin-register-components@next -D

配置 VuePress 2

编辑 VuePress 2.x 的 .vuepress/config.ts 配置文件,指定自定义组件所在的目录,该目录下的 Vue 文件会被自动注册为 Vue 组件,详细介绍可以看 这里

  • 第一种配置方式
1
2
3
4
5
6
7
8
9
10
11
import { registerComponentsPlugin } from '@vuepress/plugin-register-components'
import { getDirname, path } from '@vuepress/utils'
const __dirname = getDirname(import.meta.url)

export default {
plugins: [
registerComponentsPlugin({
componentsDir: path.resolve(__dirname, './components'),
})
]
}
  • 第二种配置方式
1
$ npm install app-root-path -D
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import path from 'path'
import appRoot from 'app-root-path';
import { registerComponentsPlugin } from '@vuepress/plugin-register-components'

// 获取 ".vupress" 目录的绝对路径
const __dirname = appRoot.resolve('./.vuepress/');

// 如果文档项目存放在工程的子目录中,比如在 "/docs" 文件夹,则写法如下
// const __dirname = appRoot.resolve('./docs/.vuepress/');

export default {
plugins: [
registerComponentsPlugin({
componentsDir: path.resolve(__dirname, './components'),
})
]
}

提示

上述的两种方式,都可以指定 VuePress 2.x 的自定义组件目录为 ./components,该目录默认存放在 .vuepress 目录下,即完整的自定义组件目录的路径是 .vuepress/components/

自定义 Mermaid 组件

在上面的自定义组件目录下,创建 mermaid.vue 源文件,例如源文件路径为 .vuepress/components/mermaid.vue,文件的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<template>
<div class="mermaid">
<slot></slot>
</div>
</template>

<script>
export default {
mounted() {
import("mermaid/dist/mermaid").then((m) => {
m.initialize({
startOnLoad: true,
});
m.init();
});
},
updated() {
import("mermaid/dist/mermaid").then((m) => {
m.initialize({
startOnLoad: true,
});
m.init();
});
}
};
</script>

Markdown 渲染

语法说明

在 MarkDown 文件内添加 <mermaid> 标签,Mermaid 的内容需要使用 {{ 包裹住,并写在 <mermaid> 标签内(如下所示)。特别注意,<mermaid> 标签内不允许存在空行。

1
2
3
4
5
<mermaid>
{{`
......(Mermaid 的内容)
`}}
</mermaid>

使用示例

流程图
1
2
3
4
5
6
7
8
9
10
11
<mermaid>
{{`
graph TB
id1(圆角矩形)--普通线-->id2[矩形];
subgraph 子图
id2==粗线==>id3{菱形}
id3-.虚线.->id4>右向旗帜]
id3--无箭头---id5((圆形))
end
`}}
</mermaid>

时序图
1
2
3
4
5
6
7
8
9
10
11
12
13
<mermaid>
{{`
sequenceDiagram
Alice->>John: Hello John, how are you?
loop Healthcheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts!
John-->>Alice: Great!
John->>Bob : How about you?
Bob-->>John : Jolly good!
`}}
</mermaid>

饼图
1
2
3
4
5
6
7
8
9
10
<mermaid>
{{`
pie
title Key elements in Product X
"Calcium" : 42.96
"Potassium" : 50.05
"Magnesium" : 10.01
"Iron" : 5
`}}
</mermaid>

类别图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<mermaid>
{{`
classDiagram
Animal <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
`}}
</mermaid>

甘特图
1
2
3
4
5
6
7
8
9
10
11
12
<mermaid>
{{`
gantt
section Section
Completed: done, des1, 2014-01-06, 2014-01-08
Active : active, des2, 2014-01-07, 3d
Parallel 1 : des3, after des1, 1d
Parallel 2 : des4, after des1, 1d
Parallel 3 : des5, after des3, 1d
Parallel 4 : des6, after des4, 1d
`}}
</mermaid>

状态图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<mermaid>
{{`
stateDiagram
[*]-->Active
state Active {
[*]-->NumLockOff
NumLockOff-->NumLockOn : EvNumLockPressed
NumLockOn-->NumLockOff : EvNumLockPressed
--
[*]-->CapsLockOff
CapsLockOff-->CapsLockOn : EvCapsLockPressed
CapsLockOn-->CapsLockOff : EvCapsLockPressed
--
[*]-->ScrollLockOff
ScrollLockOff-->ScrollLockOn : EvCapsLockPressed
ScrollLockOn-->ScrollLockOff : EvCapsLockPressed
}
`}}
</mermaid>

实体关系图
1
2
3
4
5
6
7
8
<mermaid>
{{`
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
`}}
</mermaid>

参考博客