做者博客地址: 管鲍切思世所稀的博客... , 移动端和PC端有差异哦~前几天看到掘金上有人用Vuepress搭建博客,知道vuepress的我,却历来没有亲自上手过,因而乎瞎琢磨一下。总结:vuepress仍是很强的,操做简单,没有那么难,只要你认真阅读了文章,你能够作vuepress的爸爸了。这篇文章通俗易懂,从起步到结束,按顺序讲解,认真看完你就是最靓的仔~css
本博客是基于vuepress搭建而成,什么是vuepress? => vuepress是以Vue驱动的静态网站生成器。VuePress 由两部分组成:第一部分是一个极简静态网站生成器,它包含由 Vue 驱动的主题系统和插件 API,另外一个部分是为书写技术文档而优化的默认主题,它的诞生初衷是为了支持 Vue 及其子项目的文档需求。html
你可能须要30-50分钟时间读完它,才能胜任vuepress
# 安装 yarn global add vuepress # 或者:npm install -g vuepress # 新建一个 markdown 文件 echo '# Hello VuePress!' > README.md # 开始写做 vuepress dev . # 构建静态文件 vuepress build .
注意:请确保你的 Node.js 版本 >= 8.6。
事实上,一个 VuePress 网站是一个由 Vue、Vue Router 和 webpack 驱动的单页应用。若是你之前使用过 Vue 的话,当你在开发一个自定义主题的时候,你会感觉到很是熟悉的开发体验,你甚至可使用 Vue DevTools 去调试你的自定义主题。前端
在构建时,咱们会为应用建立一个服务端渲染(SSR)的版本,而后经过虚拟访问每一条路径来渲染对应的HTML。这种作法的灵感来源于 Nuxt 的 nuxt generate
命令,以及其余的一些项目,好比 Gatsbyvue
官方话就不扯了,更多官方术语详情请移步 官方
请确保你的 Node.js 版本 >= 8。
若是你只是想尝试一下 VuePress,你能够全局安装它:java
# 安装 yarn global add vuepress # 或者:npm install -g vuepress # 新建一个 markdown 文件 echo '# Hello VuePress!' > README.md # 开始写做 vuepress dev . # 构建静态文件 vuepress build .
若是你想在一个现有项目中使用 VuePress,同时想要在该项目中管理文档,则应该将 VuePress 安装为本地依赖。做为本地依赖安装让你可使用持续集成工具,或者一些其余服务(好比 Netlify)来帮助你在每次提交代码时自动部署。webpack
# 将 VuePress 做为一个本地依赖安装 yarn add -D vuepress # 或者:npm install -D vuepress # 新建一个 docs 文件夹 mkdir docs # 新建一个 markdown 文件 echo '# Hello VuePress!' > docs/README.md # 开始写做 npx vuepress dev docs
注意若是你的现有项目依赖了 webpack 3.x,推荐使用 Yarn 而不是 npm 来安装 VuePress。由于在这种情形下,npm 会生成错误的依赖树。
接着,在 package.json
里加一些脚本:ios
{ "scripts": { "docs:dev": "vuepress dev docs", "docs:build": "vuepress build docs" } }
而后就能够开始写做了:git
yarn docs:dev # 或者:npm run docs:dev
要生成静态的 HTML 文件,运行:es6
yarn docs:build # 或者:npm run docs:build
默认状况下,文件将会被生成在 .vuepress/dist
,固然,你也能够经过 .vuepress/config.js
中的 dest
字段来修改,生成的文件能够部署到任意的静态文件服务器上,参考 部署 来了解更多。github
VuePress 遵循 “约定优于配置” 的原则,推荐的目录结构以下:
注意vuepress约定入口目录必须是 docs ,务必根目录是docs
. ├── docs │ ├── .vuepress (可选的) → 官方标注可选,不过通常都会用这个文件夹,核心文件夹 │ │ ├── components (可选的) → 这个文件夹一些以.vue结尾的vue组件,能够在markdown文件里使用 │ │ ├── theme (可选的) → 能够配置本身的博客 │ │ │ └── Layout.vue │ │ ├── public (可选的) → 放一些公共静态资源 使用方式 /xxx, 请必须以 `/` 开始表示根 │ │ ├── styles (可选的) → 样式 │ │ │ ├── index.styl → 自定义样式 │ │ │ └── palette.styl → 用于重写默认颜色常量,或者设置新的 stylus 颜色常量 │ │ ├── templates (可选的, 谨慎配置) │ │ │ ├── dev.html → 用于开发环境的 HTML 模板文件 │ │ │ └── ssr.html → 构建时基于 Vue SSR 的 HTML 模板文件 │ │ ├── config.js (可选的) → 配置文件的入口文件,也能够是 YML 或 toml │ │ └── enhanceApp.js (可选的) → 客户端应用的加强 │ │ │ ├── README.md │ ├── guide │ │ └── README.md │ └── config.md │ └── package.json
注意当你想要去自定义 templates/ssr.html 或 templates/dev.html 时,最好基于 默认的模板文件 来修改,不然可能会致使构建出错。
此外,对于上述的目录结构,默认页面路由地址以下:
文件的相对路径 | 页面路由地址 |
---|---|
/README.md | / |
/guide/README.md | /guide/ |
/config.md | /config.html |
// dcos/.vuepress/config.js module.exports = { title:"取舍", // HTML的title description:"管鲍切思世所稀博客", // 描述 keywords:"管鲍切思世所稀博客", // 关键字 head:[ // 配置头部 [ ['link', {rel:'icon', href:"/icon.png"}], ['meta', {'name':'viewport', content:"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;"}] ] ], markdown: { lineNumbers: true, // 代码显示行号 }, dest:"./outer", // 设置打包路径 lastUpdated: 'Last Updated', // 显示更新时间 themeConfig:{ logo:"/icon.png", // 导航栏左边logo,不写就不显示 sidebarDepth: 2, // 侧边栏显示2级 nav:[ // 导航栏配置 { text: 'vue', link: '/' }, { text: 'css', link: '/blog/' }, { text: 'js', // 这里是下拉列表展示形式。 items能够一直嵌套下去 items:[ text:"ES5", link:"/js/es5/", text:"ES6", link:"/js/es6/", ] }, {text: 'github', link:"https://github.com/1046224544"} ], // 为如下路由添加侧边栏 sidebar: ['/', '/git', '/vue'] // 嵌套侧边栏 以对象的方式嵌套下去 // sidebar: { // '/2019/': [ // ['','前言(2019)'], // { // title:"10月份", // collapsable:false, // sidebarDepth:2, // children:[ // ["Nginx部署Vue项目", "Nginx部署Vue项目"], // ["NVM自由切换Node版本", "NVM自由切换Node版本小笔记"], // ["KTV点歌系统", "KTV点歌系统"], // ] // }, // { // title:"9月份", // collapsable:false, // sidebarDepth:2, // children:[ // ["综合性博客网站", "综合性博客网站"] // ] // } // ], // ... // } }, plugins:[ // 'axios' // 配置插件 ] } }
注意以上就是完整的基本config.js
配置文件,有强迫症的同窗确定会以为文件大了,很差维护。的确,当咱们的路有文件变多了,文件会变得很长。笔者在这里推荐,将导航栏
和侧边栏
单独拆分两个文件,以文件加载的方式引入,这样路由导航栏
和侧边栏
就能够无限嵌套,你也能够无限往下分级,建文件夹等等达到分类效果。
以下:
// docs/.vuepress/config.js module.exports = { ...部分(同上) themeConfig:{ nav: require('./nav'), // 引入导航栏 sidebar:require('./sidebar'), // 引入侧边栏 }, ... } // docs/.vuepress/sidebar.js module.exports = { "/api/front/2019/": require('../.vuepress/frontbar/2019'), // 继续分类 "/api/front/2020/": require('../.vuepress/frontbar/2020'), "/api/end/2019/": require('../.vuepress/endbar/2019'), "/api/learn/koa/": require('../.vuepress/learnbar/koabar'), "/api/learn/express/": require('../.vuepress/learnbar/expressbar'), "/api/learn/java/": require('../.vuepress/learnbar/javabar'), "/api/learn/es6/": require('../.vuepress/learnbar/es6bar'), "/api/learn/vue/": require('../.vuepress/learnbar/vuebar'), } // docs/.vuepress/nav.js module.exports = [ {text:"首页", link:"/"}, { text:"技术API", ariLabel:"技术API", items:[ {text:"koa", link:"/api/learn/koa/"}, {text:"vue", link:"/api/learn/vue/"}, {text:"es6", link:"/api/learn/es6/"}, {text:"java", link:"/api/learn/java/"}, {text:"express", link:"/api/learn/express/"}, ] }, { text:"平常博客", ariLabel:"平常博客", items:[ {text:"前端",link:"/api/front/"}, {text:"后端",link:"/api/end/"}, {text:"其余",link:"/api/orther/1.md"}, ] }, {text:"关于博客", link:"/api/builog/"}, {text:"关于做者", link:"/api/author/"}, { text:"其余小站", ariLabel:"其余小站", items:[ {text:"掘金", link:'https://juejin.im/user/5d1079ab6fb9a07ed4410cc0'}, {text:"SegmentFault", link:'https://segmentfault.com/u/98kk'}, {text:"CSDN", link:'https://blog.csdn.net/weixin_43374176'}, ] }, { text:"联系", ariLabel:"联系", items:[ {text:"邮箱", link:"mailto:wsm_1105@163.com", target:"_blank"}, {text:"其余", link:"/api/contact/"} ] }, {text:"GitHub", link:"http://github.com/1046224544"} ]
笔者目录截图:
注意只要是本身配置的目录,都必须在docs目录下有对应的目录结构, 若是你的路径是/api/aboutme/
, 那么对象的文件目录就是/docs/api/aboutme/readme.md
,默认根路径就是readme.md
文件。 若是你的路径是/api/aboutme/ktv点歌系统
, 那么对象的文件目录就是/docs/api/aboutme/ktv点歌系统.md
单文件
的方式一致,有些时候咱们有可能须要使用 Vue 的 UI 组件库。例如 Element
, Mint
等,一般咱们在项目中使用这些 UI 组件库的时候,咱们都会在 main.js
或 botostrap.js
文件中统一注册。好在 VuePress 中也支持这种功能,咱们能够经过建立一个 .vuepress/enhanceApp.js
文件来作一些应用级别的配置,这个文件 exprot default 一个钩子函数
,在这个钩子中你能够作一些特殊处理,例如添加全局路由钩子,注册外部组件库。// .vuepress/enhanceApp.js // 全局注册 Element 组件库 import Vue from 'vue' import Element from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' export default ({ Vue, options, router }) => { Vue.use(Element) } // 在vue中使用第三方库 // 定义一个vue组件 /docs/.vuepress/componets/demo.vue <template> <div class="demo"> {{ msg }} <my-hello></my-hello> <el-button>button</el-button> // 使用了el-button </div> </template> <script> export default { data () { return { msg: 'Hello VuePress!' } } } </script>
请确保只在 beforeMount 或者 mounted 访问浏览器 / DOM 的 API。
若是你正在使用,或者须要展现一个对于 SSR 不怎么友好的组件(好比包含了自定义指令),你能够将它们包裹在内置的 <ClientOnly>
组件中:
<ClientOnly> <demo /> </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>
参考:
网站内部的连接,将会被转换成 <router-link>
用于 SPA 导航。同时,站内的每个文件夹下的 README.md
或者 index.md
文件都会被自动编译为 index.html
,对应的连接将被视为 /
。
以以下的文件结构为例:
. ├─ README.md ├─ foo │ ├─ README.md │ ├─ one.md │ └─ two.md └─ bar ├─ README.md ├─ three.md └─ four.md
假设你如今在 foo/one.md
中:
[Home](/) <!-- 跳转到根部的 README.md --> [foo](/foo/) <!-- 跳转到 foo 文件夹的 index.html --> [foo heading](./#heading) <!-- 跳转到 foo/index.html 的特定标题位置 --> [bar - three](../bar/three.md) <!-- 具体文件可使用 .md 结尾(推荐) --> [bar - four](../bar/four.html) <!-- 也能够用 .html -->
VuePress 支持重定向到干净连接。若是一个连接 /foo
找不到,VuePress 会自行寻找一个可用的 /foo/
或 /foo.html
。反过来,当 /foo/
或 /foo.html
中的一个找不到时,VuePress 也会尝试寻找另外一个。借助这种特性,咱们能够经过官方插件 vuepress-plugin-clean-urls 定制你的网站路径。
注意不管是否使用了 permalink 和 clean-urls 插件,你的相对路径都应该依赖于当前的文件结构来定义。在上面的例子中,即便你将/foo/one.md
的路径设为了/foo/one/
,你依然应该经过./two.md
来访问/foo/two.md
。
外部的连接将会被自动地设置为 target="_blank" rel="noopener noreferrer":
你能够自定义经过配置 config.markdown.externalLinks 来自定义外部连接的特性
VuePress 提供了对 YAML front matter 开箱即用的支持:
--- title: Blogging Like a Hacker lang: en-US ---
这些数据能够在当前 markdown 的正文,或者是任意的自定义或主题组件中使用。
想了解更多,请移步 Front Matter
输入
| Tables | Are | Cool | | ------------- |:-------------:| -----:| | col 3 is | right-aligned | $1600 | | col 2 is | centered | $12 | | zebra stripes | are neat | $1 |
输出
Tables | Are | Cool |
---|---|---|
col 3 is | right-aligned | $1600 |
col 2 is | centered | $12 |
zebra stripes | are neat | $1 |
输入
:tada: :100:
输出
你能够在这个列表找到全部可用的 Emoji。
输入
[[toc]]
输出
目录(Table of Contents)的渲染能够经过 markdown.toc
选项来配置。
输入
::: tip This is a tip ::: ::: warning This is a warning ::: ::: danger This is a dangerous warning :::
输出
::: tip
This is a tip
:::
::: warning
This is a warning
:::
::: danger
This is a dangerous warning
:::
你也能够自定义块中的标题:
::: danger STOP Danger zone, do not proceed :::
::: danger STOP
Danger zone, do not proceed
:::
参考:
VuePress 使用了 Prism 来为 markdown 中的代码块实现语法高亮。Prism 支持大量的编程语言,你须要作的只是在代码块的开始倒勾中附加一个有效的语言别名:
输入
export default { name: 'MyComponent', // ... } ```
**输出**
export default {
name: 'MyComponent',
// ...
}
**输入**
<ul> <li v-for="todo in todos" :key="todo.id" > {{ todo.text }} </li> </ul>
**输出**
<ul>
<li
v-for="todo in todos" :key="todo.id"
{{ todo.text }}
</li>
</ul>
## 代码块中的行高亮 **输入**
export default { data () { return { msg: 'Highlighted!' } } }
**输出**
export default {
data () {
return { msg: 'Highlighted!' }
}
}
## 行号 你能够经过配置来为每一个代码块显示行号:
module.exports = {
markdown: {
lineNumbers: true
}
}
## 导入代码段 你能够经过下述的语法导入已经存在的文件中的代码段:
<<< @/filepath
它也支持 行高亮:
<<< @/filepath{highlightLines}
>**注意**因为代码段的导入将在 webpack 编译以前执行,所以你没法使用 webpack 中的路径别名,此处的 `@` 默认值是 `process.cwd()`。 ## 进阶配置 VuePress 使用 [markdown-it](https://github.com/markdown-it/markdown-it) 来渲染 Markdown,上述大多数的拓展也都是经过自定义的插件实现的。想要进一步的话,你能够经过 `.vuepress/config.js` 的` markdown` 选项,来对当前的 `markdown-it` 实例作一些自定义的配置:
module.exports = {
markdown: {
// markdown-it-anchor 的选项 anchor: { permalink: false }, // markdown-it-toc 的选项 toc: { includeLevel: [1, 2] }, extendMarkdown: md => { // 使用更多的 markdown-it 插件! md.use(require('markdown-it-xxx')) }
}
}
## 评论系统 Valine >看完本节内容,你就能够胜任Valine了,今后网站不在寂静,本评论系统通俗易懂,彻底能够解决其余做者讲解此部分留下的后遗症,赶忙收藏吧! - 须要安装leancloud-storage和valine - [valine官网](https://valine.js.org/quickstart.html) - appid和appkey的获取须要注册[leancloud](https://leancloud.cn/),而后能够新建应用并在`设置>应用 key`能够查看 ### 安装
npm install leancloud-storage --save
npm install valine --save
### 配置 Components.vue组件
// 新建Components.vue组件
<template>
<div class="vcomment" v-if="data.comments === true"> <div id="vcomments"></div> </div>
</template>
<script>
import { isActive, hashRE, groupHeaders } from '../util'
export default {
computed: {
data () { return this.$page.frontmatter },
},
mounted: function(){
this.createValine()
},
methods: {
createValine() { const Valine = require('valine'); window.AV = require('leancloud-storage'); const valine = new Valine({ el: '#vcomments', appId: 'your ID', appKey: 'your Key', notify: false, verify: false, avatar: 'monsterid', path: window.location.pathname, placeholder: '同道中人,文明留言...', }); this.valineRefresh = false }
},
watch: {
'$route' (to, from) { if(to.path !== from.path){ setTimeout(() => { //从新刷新valine this.createValine() }, 180) } }
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
max-width 740px
padding 10px
display block;
margin-left auto;
margin-right auto;
}
</style>
Page.vue
// Page.vue
<template>
<main class="page">
<slot name="top" /> <Content class="theme-default-content" /> <PageEdit /> <PageNav v-bind="{ sidebarItems }" /> <slot name="bottom" /> <Comments v-bind:is="viewComments"></Comments>
</main>
</template>
<script>
import PageEdit from '@theme/components/PageEdit.vue'
import PageNav from '@theme/components/PageNav.vue'
import { resolvePage, normalize, outboundRE, endingSlashRE } from '../util'
import Comments from './Comments.vue'
export default {
components: { PageEdit, PageNav , Comments},
props: ['sidebarItems'],
data(){
return{ viewComments: 'Comments', }
}
}
</script>
<style lang="stylus">
@require '../styles/wrapper.styl'
.page
padding-bottom 2rem
display block
</style>
### 使用(按需使用) 好比你想在china.md 文件中使用, 你就在头部 贴入一下代码 评论系统不是每一个页面都同样的,根据不一样的页面,加载不一样的评论, 看了不少小编说什么评论的乱七八糟,看完这篇文章,对Valine再也不那么恐慌,让你玩转第三方评论
**截图**   >Valine实例与leancloud-storage实例 在每次页面加载时会向服务器发起带当前url参数的请求以获取评论数据,而这个url参数每次都是同样。首先Valine 实例与 leancloud-storage 实例都在 mounted 钩子中初始化或挂载至 window 对象上了。当页面 url 变化时,Page.vue 自己并无变化,但mounted会从新触发。 ## 关于其余插件 你能够移步到官网查看,插件就是给咱们用的,若是难的话,还叫什么插件,只要认真看,你总会看懂的 ## 部署到 Github pages 当咱们将文档写好后就到了咱们最关心的地方了,怎么将打包后的代码推送到远程仓库的 `gh-pages` 分支上,网上应该有不少文章描述怎么作,可是不少方法比较麻烦,还好有工具已经为咱们解决了这个麻烦了。 ### 建立一个deploy.sh
touch deploy.sh
### 编写脚本
set -e
npm run docs:build
cd docs/.vuepress/dist
git init
git add -A
git commit -m 'deploy'
cd -
### 设置package.json
{
"scripts": { "deploy": "bash deploy.sh" },
}
### 发布
npm run deploy // 便可自动构建部署到github上。
**详情移步官网** - [vuepress.vuejs.org](https://vuepress.vuejs.org/zh/guide/deploy.html) ## 总结 相比较 Hexo 而言 VuePress 上手更加容易,功能也更强大,例如在 VuePress 能够注册自定义组件,并且 VuePress 中编写 Vue 和平时同样学习成本几乎为零。因此若是您正在开源一款 Vue 相关的库或是其余项目,您均可以使用 VuePress 做为您的文档编辑工具。虽然并无彻底将 VuePress 内容讲完,学完该篇文章相信你能够对 VuePress 有个大概的了解,您至少能够快速搭建一个博客,若是您想对 VuePress 有更多了解,请参考 [Vuepress 中文 API](https://vuepress.vuejs.org/zh/) ## 在线查看 [管鲍切思世所稀的博客...](https://blog.usword.cn/api/builog/) >移动端和PC端有差异哦~ ## 博客部分截图    ## 其余 - [完整的综合性网站](https://juejin.im/post/5da2a8ed6fb9a04de818eeff) - [KTV点歌系统](https://juejin.im/post/5dac3b4351882576534d33d7) - [Nginx部署Vue项目](https://juejin.im/post/5dbbb4df51882522c14f81a8) - [NVM的使用小技巧](https://juejin.im/post/5dae55b75188257d8936be94) ## 联系 若是你们有兴趣,欢迎关注公众号:_facebook(web技术进阶),查看更多优质文章,欢迎你们加入个人前端交流群:[866068198](https://qm.qq.com/cgi-bin/qm/qr?k=m8asYpHTs_cw3lJVLVv4U6wbF4ep2Ny5&authKey=OknnnniiEOFaIZNhEl2dUIhSrKPB8wGrEYu1AGyS01Y6XXz7doQl7v%2FitvPRr3ii) ,一块儿交流学习前端技术。博主目前一直在自学Node中,技术有限,若是能够,会尽力给你们提供一些帮助,或是一些学习方法. - 公众号  - QQ群 <a href="https://qm.qq.com/cgi-bin/qm/qr?k=m8asYpHTs_cw3lJVLVv4U6wbF4ep2Ny5&authKey=OknnnniiEOFaIZNhEl2dUIhSrKPB8wGrEYu1AGyS01Y6XXz7doQl7v%2FitvPRr3ii" style="display:flex;align-items:center;justify-content:center;"> <img src="https://user-gold-cdn.xitu.io/2019/11/23/16e974e0f084ca30?w=540&h=740&f=jpeg&s=125975"> </a> ## 福利 有须要刷钻,刷会员,刷腾讯视频会员,涨粉丝等等相关意向的小伙伴们,能够访问做者推荐的超值代刷网站:[qq.usword.cn](http://qq.usword.cn), 也能够扫描下方二维码  ## 最后 >若是老板以为这篇文章有帮助,就大方的点个赞吧,老板大气,老板最帅~ If you have some questions after you see this article, you can contact me or you can find some info by clicking these links. - [juejin@wsm's juejin](https://juejin.im/user/5d1079ab6fb9a07ed4410cc0) - Gi[tHub@1046224544](https://github.com/1046224544) - [Segmentfault@wsm](https://segmentfault.com/u/98kk)