VuePress 笔记
介绍
VuePress 由两部分组成:一个以 Vue 驱动的主题系统的简约静态网站生成工具,和一个为编写技术文档而优化的默认主题。它是为了支持 Vue 子项目的文档需求而创建的。
由 VuePress 生成的每个页面,都具有相应的预渲染静态 HTML,它们能提供出色的加载性能,并且对 SEO 友好。然而,页面加载之后,Vue 就会将这些静态内容,接管为完整的单页面应用程序(SPA)。当用户在浏览站点时,可以按需加载其他页面。
特性
- 内置 markdown 扩展,针对技术文档进行了优化
- 能够利用内嵌在 markdown 文件中的 Vue 代码
- 以 Vue 驱动的自定义主题系统
- PWA 支持
- Google Analytics 集成
- 一个默认主题:
- 响应式布局
- 可选的主页
- 简单、开箱即用、基于标题的搜索功能
- 可定制的导航栏和侧边栏
- 自动生成的 GitHub 链接和页面编辑链接
#待实现特性(todo features)
VuePress 的开发仍在进行中。有几件目前不支持,但计划做的功能:
- 多语言支持
- Algolia DocSearch 集成
- 博客支持
快速上手
全局安装
如果你只是想随便用下 VuePress,你可以在全局安装它:
# 全局安装
npm install -g vuepress
# 创建一个 markdown 文件
echo '# Hello VuePress' > README.md
# 开始编写文档
vuepress dev
# 构建
vuepress build
在已有项目中安装
如果你想要在一个已有项目中维护文档,就应该将 VuePress 安装为本地依赖。此设置还允许你使用 CI 或 Netlify 服务,在推送时自动部署。
# 安装为本地依赖项
npm install -D vuepress
# 创建一个 docs 目录
mkdir docs
# 创建一个 markdown 文件
echo '# Hello VuePress' > docs/README.md
# 开始编写文档
npx vuepress dev docs
或者,给 package.json 添加一些 scripts 脚本:
{
"scripts": {
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs"
}
}
然后你就可以开始编写文档了:
npm run docs:dev
要生成静态资源,请运行:
npm run docs:build
默认情况下,构建的文件会位于 .vuepress/dist 中,该文件可以通过 .vuepress/config.js 中的 dest 字段进行配置。构建的文件可以部署到任何静态文件服务器。关于如何部署到一些常用服务,请参考 部署指南。
目录结构
VuePress 遵循 “约定优于配置” 的原则,推荐的目录结构如下:
├── docs
│ ├── .vuepress (可选的)
│ │ ├── components (可选的)
│ │ ├── theme (可选的)
│ │ │ └── Layout.vue
│ │ ├── public (可选的)
│ │ ├── styles (可选的)
│ │ │ ├── index.styl
│ │ │ └── palette.styl
│ │ ├── templates (可选的, 谨慎配置)
│ │ │ ├── dev.html
│ │ │ └── ssr.html
│ │ ├── config.js (可选的)
│ │ └── enhanceApp.js (可选的)
│ │
│ ├── README.md
│ ├── guide
│ │ └── README.md
│ └── config.md
│
└── package.json
注意
请留意目录名的大写。
docs/.vuepress: 用于存放全局的配置、组件、静态资源等。docs/.vuepress/components: 该目录中的 Vue 组件将会被自动注册为全局组件。docs/.vuepress/theme: 用于存放本地主题。docs/.vuepress/styles: 用于存放样式相关的文件。docs/.vuepress/styles/index.styl: 将会被自动应用的全局样式文件,会生成在最终的 CSS 文件结尾,具有比默认样式更高的优先级。docs/.vuepress/styles/palette.styl: 用于重写默认颜色常量,或者设置新的 stylus 颜色常量。docs/.vuepress/public: 静态资源目录。docs/.vuepress/templates: 存储 HTML 模板文件。docs/.vuepress/templates/dev.html: 用于开发环境的 HTML 模板文件。docs/.vuepress/templates/ssr.html: 构建时基于 Vue SSR 的 HTML 模板文件。docs/.vuepress/config.js: 配置文件的入口文件,也可以是YML或toml。docs/.vuepress/enhanceApp.js: 客户端应用的增强。
注意
当你想要去自定义
templates/ssr.html或templates/dev.html时,最好基于 默认的模板文件 (opens new window)来修改,否则可能会导致构建出错。
基本配置
base
- 类型:
string - 默认值:
/
部署站点的基础路径,如果你想让你的网站部署到一个子路径下,你将需要设置它。如 GitHub pages,如果你想将你的网站部署到 https://foo.github.io/bar/,那么 base 应该被设置成 "/bar/",它的值应当总是以斜杠开始,并以斜杠结束。
base 将会作为前缀自动地插入到所有以 / 开始的其他选项的链接中,所以你只需要指定一次。
参考:
#title
- 类型:
string - 默认值:
undefined
网站的标题,它将会被用作所有页面标题的前缀,同时,默认主题下,它将显示在导航栏(navbar)上。
#description
- 类型:
string - 默认值:
undefined
网站的描述,它将会以 `` 标签渲染到当前页面的 HTML 中。
#head
- 类型:
Array - 默认值:
[]
额外的需要被注入到当前页面的 HTML `` 中的标签,每个标签都可以以 [tagName, { attrName: attrValue }, innerHTML?] 的格式指定,举个例子,增加一个自定义的 favicon:
module.exports = {
head: [
['link', { rel: 'icon', href: '/logo.png' }]
]
}
#host
- 类型:
string - 默认值:
'0.0.0.0'
指定用于 dev server 的主机名。
#port
- 类型:
number - 默认值:
8080
指定 dev server 的端口。
#temp
- Type:
string - Default:
/path/to/@vuepress/core/.temp
指定客户端文件的临时目录。
#dest
- 类型:
string - 默认值:
.vuepress/dist
指定 vuepress build 的输出目录。如果传入的是相对路径,则会基于 process.cwd() 进行解析。
#locales
- 类型:
{ [path: string]: Object } - 默认值:
undefined
提供多语言支持的语言配置。具体细节请查看 多语言支持。
#shouldPrefetch
- 类型:
Function - 默认值:
() => true
一个函数,用来控制对于哪些文件,是需要生成 `` 资源提示的。请参考 shouldPrefetch (opens new window)。
#cache
- 类型:
boolean|string - 默认值:
true
VuePress 默认使用了 cache-loader (opens new window)来大大地加快 webpack 的编译速度。
此选项可以用于指定 cache 的路径,同时也可以通过设置为 false 来在每次构建之前删除 cache。
提示
这个选项也可以通过命令行来使用:
vuepress dev docs --cache .cache # 设置 cache 路径 vuepress dev docs --no-cache # 在每次构建前删除 cache
#extraWatchFiles
- 类型:
Array - 默认值:
[]
指定额外的需要被监听的文件。
你可以监听任何想监听的文件,文件变动将会触发 vuepress 重新构建,并实时更新。
module.exports = {
extraWatchFiles: [
'.vuepress/foo.js', // 使用相对路径
'/path/to/bar.js' // 使用绝对路径
]
}
#patterns
- Type:
Array - Default:
['**/*.md', '**/*.vue']
Specify which pattern of files you want to be resolved.
#Styling
#palette.styl
如果要对默认预设 (opens new window)的样式进行简单的替换,或者定义一些变量供以后使用,你可以创建一个 .vuepress/styles/palette.styl 文件。
你可以调整的一些变量如下:
// 颜色
$accentColor = #3eaf7c
$textColor = #2c3e50
$borderColor = #eaecef
$codeBgColor = #282c34
$arrowBgColor = #ccc
$badgeTipColor = #42b983
$badgeWarningColor = darken(#ffe564, 35%)
$badgeErrorColor = #DA5961
// 布局
$navbarHeight = 3.6rem
$sidebarWidth = 20rem
$contentWidth = 740px
$homePageWidth = 960px
// 响应式变化点
$MQNarrow = 959px
$MQMobile = 719px
$MQMobileNarrow = 419px
警告
你应该只在这个文件中定义变量。因为
palette.styl将在根的 stylus 配置文件的末尾引入,作为配置,它将被多个文件使用,所以一旦你在这里写了样式,你的样式就会被多次复制。
#index.styl
VuePress 提供了一种添加额外样式的简便方法。你可以创建一个 .vuepress/styles/index.styl 文件。这是一个 Stylus (opens new window)文件,但你也可以使用正常的 CSS 语法。
.content {
font-size 30px
}
注意
由于背后的行为,不论是在
palette.styl或是index.styl,都不能透过 @import / @require (opens new window)從相对路径引用一般的.css样式表。
参考:
#主题
#theme
- 类型:
string - 默认值:
undefined
当你使用自定义主题的时候,需要指定它。
参考:
- 使用主题.
#themeConfig
- 类型:
Object - 默认值:
{}
为当前的主题提供一些配置,这些选项依赖于你正在使用的主题。
也可以参考:
- 默认主题。
#Pluggable
#plugins
- 类型:
Object|Array - 默认值:
undefined
请参考 plugin > Using a plugin 来使用一个插件。
#Markdown
#markdown.lineNumbers
- 类型:
boolean - 默认值:
undefined
是否在每个代码块的左侧显示行号。
参考:
#markdown.slugify
- 类型:
Function - 默认值: source(opens new window)
一个将标题文本转换为 slug 的函数。修改它会影响 标题、目录、以及侧边栏链接的 id 和 链接。
#markdown.anchor
- 类型:
Object - 默认值:
{ permalink: true, permalinkBefore: true, permalinkSymbol: '#' }
markdown-it-anchor (opens new window)的选项。
#markdown.pageSuffix
- 类型:
string - 默认值:
.html
Option to customize internal links to be compatible when using the vuepress-plugin-clean-urls (opens new window).
#markdown.externalLinks
- 类型:
Object - 默认值:
{ target: '_blank', rel: 'noopener noreferrer' }
这个键值对将会作为特性被增加到是外部链接的 `` 标签上,默认的选项将会在新窗口中打开一个该外部链接。
#markdown.toc
- 类型:
Object - 默认值:
{ includeLevel: [2, 3] }
markdown-it-table-of-contents (opens new window)的选项。
#markdown.plugins
你可以使用 markdown.plugins 来安装 markdown-it 插件。它的使用方法与安装一个 VuePress 插件类似。你可以使用 Babel 语法或对象语法。markdown-it- 前缀同样是可以忽略的。
module.exports = {
markdown: {
plugins: [
'@org/foo', // 等价于 @org/markdown-it-foo,如果对应的包存在
['markdown-it-bar', {
// 提供你的选项
}]
]
}
}
or
module.exports = {
markdown: {
plugins: {
'@org/foo': {}
'markdown-it-bar': {
// 提供你的选项
}
}
}
}
#markdown.extendMarkdown
- 类型:
Function - 默认值:
undefined
一个用于修改当前的 markdown-it (opens new window)实例的默认配置,或者应用额外的插件的函数,举例如下:
module.exports = {
markdown: {
extendMarkdown: md => {
md.set({ breaks: true })
md.use(require('markdown-it-xxx'))
}
}
}
提示
这个选项也被 Plugin API 所支持。
#markdown.extractHeaders
- 类型:
Array - 默认值:
['h2', 'h3']
Markdown 文件的 headers (标题 & 小标题) 会在准备阶段被提取出来,并存储在 this.$page.headers 中。默认情况下,VuePress 会提取 h2 和 h3 标题。你可以通过这个选项来修改提取出的标题级别。
module.exports = {
markdown: {
extractHeaders: [ 'h2', 'h3', 'h4' ]
}
}
#构建流程
#postcss
- 类型:
Object - 默认值:
{ plugins: [require('autoprefixer')] }
postcss-loader (opens new window)的选项,请注意,指定这个值,将会覆盖内置的 autoprefixer,所以你需要自己将它加进去。
#stylus
- 类型:
Object - 默认值:
{ preferPathResolver: 'webpack' }
stylus-loader (opens new window)的选项。
#scss
- 类型:
Object - 默认值:
{}
加载 *.scss 文件的 sass-loader (opens new window)的选项。
#sass
- 类型:
Object - 默认值:
{ indentedSyntax: true }
加载 *.sass 文件的 sass-loader (opens new window)的选项。
#less
- 类型:
Object - Default:
{}
less-loader (opens new window)的选项。
#configureWebpack
- 类型:
Object | Function - 默认值:
undefined
用于修改内部的 Webpack 配置。如果给定一个对象,那么它将会被 webpack-merge (opens new window)合并到最终的配置中,如果给定一个函数,它将会接受 config 作为第一个参数,以及 isServer 作为第二个参数,你可以直接更改 config,也可以返回一个待合并的对象。
module.exports = {
configureWebpack: (config, isServer) => {
if (!isServer) {
// 修改客户端的 webpack 配置
}
}
}
#chainWebpack
- 类型:
Function - 默认值:
undefined
通过 webpack-chain (opens new window)来修改内部的 Webpack 配置。
module.exports = {
chainWebpack: (config, isServer) => {
// config 是 ChainableConfig 的一个实例
}
}
#浏览器兼容性
#evergreen
- 类型:
boolean | Function - 默认值:
false
如果你的对象只有那些 “常青树” 浏览器,你可以将其设置成 true,这将会禁止 ESNext 到 ES5 的转译以及对 IE 的 polyfills,同时会带来更快的构建速度和更小的文件体积。
在 Markdown 中使用 Vue
当你在开发一个 VuePress 应用时,由于所有的页面在生成静态 HTML 时都需要通过 Node.js 服务端渲染,因此所有的 Vue 相关代码都应当遵循 编写通用代码 (opens new window)的要求。简而言之,请确保只在 beforeMount 或者 mounted 访问浏览器 / DOM 的 API。
如果你正在使用,或者需要展示一个对于 SSR 不怎么友好的组件(比如包含了自定义指令),你可以将它们包裹在内置的 `` 组件中:
<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>
参考:
使用组件
所有在 .vuepress/components 中找到的 *.vue 文件将会自动地被注册为全局的异步组件,如:
.
└─ .vuepress
└─ components
├─ demo-1.vue
├─ OtherComponent.vue
└─ Foo
└─ Bar.vue
你可以直接使用这些组件在任意的 Markdown 文件中(组件名是通过文件名取到的):
<demo-1/>
<OtherComponent/>
<Foo-Bar/>
默认主题
首页
默认的主题提供了一个首页(Homepage)的布局 (用于 这个网站的主页)。想要使用它,需要在你的根级 README.md 的 YAML front matter 指定 home: true。以下是一个如何使用的例子:
---
home: true
heroImage: /hero.png //注意:图片要存放在`docs/.vuepress/public目录下`
heroText: Hero 标题
tagline: Hero 副标题
actionText: 快速上手 →
actionLink: /zh/guide/
features:
- title: 简洁至上
details: 以 Markdown 为中心的项目结构,以最少的配置帮助你专注于写作。
- title: Vue驱动
details: 享受 Vue + webpack 的开发体验,在 Markdown 中使用 Vue 组件,同时可以使用 Vue 来开发自定义主题。
- title: 高性能
details: VuePress 为每个页面预渲染生成静态的 HTML,同时在页面被加载的时候,将作为 SPA 运行。
footer: MIT Licensed | Copyright © 2018-present Evan You
---
富文本 footer
你还可以使用 Markdown Slot Syntax 来设置 footer,以支持富文本:
---
home: true
---
::: slot footer
MIT Licensed | Copyright © 2018-present [Evan You](https://github.com/yyx990803)
:::
导航栏
导航栏可能包含你的页面标题、搜索框、 导航栏链接、多语言切换、仓库链接,它们均取决于你的配置。
#导航栏 Logo
你可以通过 themeConfig.logo 增加导航栏 Logo ,Logo 可以被放置在公共文件目录:
// .vuepress/config.js
module.exports = {
themeConfig: {
logo: '/assets/img/logo.png',
}
}
#导航栏链接
你可以通过 themeConfig.nav 增加一些导航栏链接:
// .vuepress/config.js
module.exports = {
themeConfig: {
nav: [
{ text: 'Home', link: '/' },
{ text: 'Guide', link: '/guide/' },
{ text: 'External', link: 'https://google.com' },
]
}
}
外部链接 标签的特性将默认包含`target="_blank" rel="noopener noreferrer"`,你可以提供 `target` 与 `rel`,它们将被作为特性被增加到 标签上:
// .vuepress/config.js
module.exports = {
themeConfig: {
nav: [
{ text: 'External', link: 'https://google.com', target:'_self', rel:'' },
{ text: 'Guide', link: '/guide/', target:'_blank' }
]
}
}
当你提供了一个 items 数组而不是一个单一的 link 时,它将显示为一个 下拉列表 :
// .vuepress/config.js
module.exports = {
themeConfig: {
nav: [
{
text: 'Languages',
ariaLabel: 'Language Menu',
items: [
{ text: 'Chinese', link: '/language/chinese/' },
{ text: 'Japanese', link: '/language/japanese/' }
]
}
]
}
}
此外,你还可以通过嵌套的 items 来在 下拉列表 中设置分组:
// .vuepress/config.js
module.exports = {
themeConfig: {
nav: [
{
text: 'Languages',
items: [
{ text: 'Group1', items: [/* */] },
{ text: 'Group2', items: [/* */] }
]
}
]
}
}
禁用导航栏
你可以使用 themeConfig.navbar 来禁用所有页面的导航栏:
// .vuepress/config.js
module.exports = {
themeConfig: {
navbar: false
}
}
你也可以通过 YAML front matter 来禁用某个指定页面的导航栏:
---
navbar: false
---
侧边栏
想要使 侧边栏(Sidebar)生效,需要配置 themeConfig.sidebar,基本的配置,需要一个包含了多个链接的数组:
// .vuepress/config.js
module.exports = {
themeConfig: {
sidebar: [
'/',
'/page-a',
['/page-b', 'Explicit link text']
]
}
}
你可以省略 .md 拓展名,同时以 / 结尾的路径将会被视为 */README.md,这个链接的文字将会被自动获取到(无论你是声明为页面的第一个 header,还是明确地在 YAML front matter 中指定页面的标题)。如果你想要显示地指定链接的文字,使用一个格式为 [link, text] 的数组。
#嵌套的标题链接
默认情况下,侧边栏会自动地显示由当前页面的标题(headers)组成的链接,并按照页面本身的结构进行嵌套,你可以通过 themeConfig.sidebarDepth 来修改它的行为。默认的深度是 1,它将提取到 h2 的标题,设置成 0 将会禁用标题(headers)链接,同时,最大的深度为 2,它将同时提取 h2 和 h3 标题。
也可以使用 YAML front matter 来为某个页面重写此值:
---
sidebarDepth: 2
---
显示所有页面的标题链接
默认情况下,侧边栏只会显示由当前活动页面的标题(headers)组成的链接,你可以将 themeConfig.displayAllHeaders 设置为 true 来显示所有页面的标题链接:
// .vuepress/config.js
module.exports = {
themeConfig: {
displayAllHeaders: true // 默认值:false
}
}
活动的标题链接
默认情况下,当用户通过滚动查看页面的不同部分时,嵌套的标题链接和 URL 中的 Hash 值会实时更新,这个行为可以通过以下的配置来禁用:
// .vuepress/config.js
module.exports = {
themeConfig: {
activeHeaderLinks: false, // 默认值:true
}
}
提示
值得一提的是,当你禁用此选项时,此功能的相应脚本将不会被加载,这是我们性能优化的一个小点。
侧边栏分组
你可以通过使用对象来将侧边栏划分成多个组:
// .vuepress/config.js
module.exports = {
themeConfig: {
sidebar: [
{
title: 'Group 1', // 必要的
path: '/foo/', // 可选的, 标题的跳转链接,应为绝对路径且必须存在
collapsable: false, // 可选的, 默认值是 true,
sidebarDepth: 1, // 可选的, 默认值是 1
children: [
'/'
]
},
{
title: 'Group 2',
children: [ /* ... */ ],
initialOpenGroupIndex: -1 // 可选的, 默认值是 0
}
]
}
}
侧边栏的每个子组默认是可折叠的,你可以设置 collapsable: false 来让一个组永远都是展开状态。
一个侧边栏的子组配置同时支持 sidebarDepth 字段用于重写默认显示的侧边栏深度(1)。
提示
嵌套的侧边栏分组也是支持的。
多个侧边栏
如果你想为不同的页面组来显示不同的侧边栏,首先,将你的页面文件组织成下述的目录结构:
.
├─ README.md
├─ contact.md
├─ about.md
├─ foo/
│ ├─ README.md
│ ├─ one.md
│ └─ two.md
└─ bar/
├─ README.md
├─ three.md
└─ four.md
接着,遵循以下的侧边栏配置:
// .vuepress/config.js
module.exports = {
themeConfig: {
sidebar: {
'/foo/': [
'', /* /foo/ */
'one', /* /foo/one.html */
'two' /* /foo/two.html */
],
'/bar/': [
'', /* /bar/ */
'three', /* /bar/three.html */
'four' /* /bar/four.html */
],
// fallback
'/': [
'', /* / */
'contact', /* /contact.html */
'about' /* /about.html */
]
}
}
}
注意
确保 fallback 侧边栏被最后定义。VuePress 会按顺序遍历侧边栏配置来寻找匹配的配置。
侧栏文件示例
---
title: Button-按钮
---
# 按钮
**简单使用**
**预览**
<ClientOnly>
<button-demos></button-demos>
</ClientOnly>
**代码**
~~~html
<g-button>默认按钮</g-button>
<g-button icon="setup">默认按钮</g-button>
<g-button :loading="true">默认按钮</g-button>
<g-button disabled>默认按钮</g-button>
~~~
vue简易UI库官网制作的 .vuepress/config.js文件
module.exports = {
base:'/goLongUi/',
title: ' goLong Ui',
description: '一个好用的UI框架',
themeConfig: {
nav: [
{text: '主页', link: '/'},
{text: 'github', link: 'https://github.com/changyulong1/golu-deom'},
],
sidebar: [
{
title: '入门',
collapsable: false,
children: [
'/install/',
'/get-started/',
]
},
{
title: '组件',
collapsable: false,
children: [
'/components/button',
'/components/tabs',
'/components/input',
'/components/grid',
'/components/layout',
'/components/toast',
'/components/popover',
'/components/Collapse',
]
}
]
}
}
官网链接
部署
下述的指南基于以下条件:
- 文档放置在项目的
docs目录中; - 使用的是默认的构建输出位置;
- VuePress 以本地依赖的形式被安装到你的项目中,并且配置了如下的 npm scripts:
{
"scripts": {
"docs:build": "vuepress build docs"
}
}
GitHub Pages
-
在
docs/.vuepress/config.js中设置正确的base。如果你打算发布到
https://.github.io/,则可以省略这一步,因为base默认即是"/"。如果你打算发布到
https://.github.io//(也就是说你的仓库在https://github.com//),则将base设置为"//"。 -
在你的项目中,创建一个如下的
deploy.sh文件(请自行判断去掉高亮行的注释):
#!/usr/bin/env sh
# 确保脚本抛出遇到的错误
set -e
# 生成静态文件
npm run docs:build
# 进入生成的文件夹
cd docs/.vuepress/dist
# 如果是发布到自定义域名
# echo 'www.example.com' > CNAME
git init
git add -A
git commit -m 'deploy'
# 如果发布到 https://<USERNAME>.github.io
# git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git master
# 如果发布到 https://<USERNAME>.github.io/<REPO>
# git push -f git@github.com:<USERNAME>/<REPO>.git master:gh-pages
cd -
TIP
你可以在你的持续集成的设置中,设置在每次 push 代码时自动运行上述脚本。