VuePress 开发个人博客进阶之自定义主题

时间:2020-9-8 作者:admin

VuePress是一个以 Vue 驱动的主题系统的简约静态网站生成工具,最初的目的是用来支持 Vue子项目的文档。但现在很多开发者都想要利用 VuePress来搭建自己的博客,特别是对于 vue 的开发者来说,因为 Vuepress的博客主题就是基于 Vue的语法去开发的。

官方提供的默认主题非常简洁,不能满足开发者定制个性化博客的需求,那怎么样自己写一个 VuePresstheme呢?相信有很多开发者已经尝试着去开发一个自定义主题,但由于vuepress的文档并不健全,很多地方没有说明,往往只能放弃。

而本文介绍了如何开发 VuePress自定义主题以及如何发布主题到 npm上,帮你踩了 Vuepress自定义主题开发博客的坑。

效果展示

VuePress  开发个人博客进阶之自定义主题

VuePress  开发个人博客进阶之自定义主题

VuePress  开发个人博客进阶之自定义主题

VuePress  开发个人博客进阶之自定义主题

以上效果是我的个人博客中用到的主题样式 vuepress-theme-mount,后续会继续完善并开放出来。如果有同学感兴趣,这里是项目的 github地址。有很多东西还没补充上去,愿意看的同学可以把它当成 demo

开始

  1. 新建 vuepress文件夹。
  2. 按照官方文档中 在已有项目中安装方法安装。
  3. 对项目进行 配置

由于这一部分官方文档中说的很清楚,按照指引即可完成,不做赘述啦。完成上述步骤后,你的目录结构应该如下:

vuepress
├─ docs
│  └─ README.md
├─ node_modules
├─ package-lock.json
└─ package.json

接着使用命令 vuepress dev docs运行,显示的是包含 hello Vuepress的页面和包含一个搜索框的 header部分,以及根目录下 README.md的内容。

自定义主题

接着我们要开始进入正题:写 theme自定义的部分。

构建目录

接着,我们根据官方文档中 开发主题/目录结构构建目录。

  1. 文档根目录下创建一个 .vuepress/theme目录,然后创建它的子目录。
theme
├── global-components //该目录下的组件都会被自动注册为全局组件
│   └── xxx.vue
├── components        // Vue 组件
│   └── xxx.vue
├── layouts           // 布局组件,其中 Layout.vue 是必需的
│   ├── Layout.vue (必要的)
│   └── 404.vue
├── styles            // 全局的样式和调色板
│   ├── index.styl
│   └── palette.styl
├── index.js         // 主题文件的入口文件
└── enhanceApp.js    // 主题水平的客户端增强文件

建好以上目录后(注意没有package.jsontemplate文件夹),运行一下 vuepress dev docs发现是空白的,说明我们的 layout.vue已经生效了。

  1. theme/index.js中加入:
module.exports = {
   // ...
}

开发 layout.vue

接下来,我们就可以按照自己想要的布局在 layout.vue中开发了。需要用到的组件都写到 theme/components下,在 layout.vue中引入即可。

例如,我想要我的整体布局分成 maincontentfooter部分。

theme
├── components        // Vue 组件
│   ├── Header.vue 
│   └── Footer.vue

layout.vue正常引入即可:

<template>
  <div>
    <Header />
    <Content />
    <Footer />
  </div>
</template>

<script>
import Header from "../components/Header"
import Footer from "../components/Footer"

export default {
  components: {
    Header,
    Footer
  }
};
</script>

写好后, 运行 npm run docs:dev即可看见你的页面。接下来就像写一个正常的 vue项目一样,开始写你自己的博客主题了。

将第三方 UI 集成到主题中

这里以开发顶部导航栏为例,示范安装第三方库 element-ui及使用。

cd 到 theme 目录下,运行命令安装:npm i element-ui -S

这里推荐按需引入,需要安装 babel-plugin-component,运行命令安装 :npm install babel-plugin-component -D

然后,theme目录下新建 .babelrc并修改为:

{
  "presets": [["es2015", { "modules": false }]],
  "plugins": [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

接下来,如果你只希望引入部分组件,比如 Menu,那么需要在 enhanceApp.js中写入以下内容:

import {
  Menu,
  Submenu,
  MenuItem,
  MenuItemGroup
} from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
export default ({
  Vue, // VuePress 正在使用的 Vue 构造函数
  options, // 附加到根实例的一些选项
  router, // 当前应用的路由实例
  siteData // 站点元数据
}) => {
  Vue.use(Menu)
  Vue.use(Submenu)
  Vue.use(MenuItem)
  Vue.use(MenuItemGroup)
}

以上步骤安装好之后,就可以在组件中使用,方法和普通的 vue项目一样。

使用vuepress 官方插件

这里以开发顶部导航栏为例,示范安装插件 search框及使用。插件的安装在 官方文档中已经说明的很清楚,这里示范一下。

安装

yarn add -D @vuepress/plugin-search
# OR npm install -D @vuepress/plugin-search

配置插件

.vuepress/config.js中:

// .vuepress/config.js or themePath/index.js
module.exports = {
  plugins: [
    ['@vuepress/search', {
      searchMaxSuggestions: 10
    }]
  ]
}

使用

search插件将自动注入指向搜索组件的 webpack别名 @SearchBox,可以直接在 layout组件中使用它:

<template>
  <div class="foo-layout">
    <header>
      <SearchBox/>
    </header>
    <main>
      ...
    </main>
  </div>
</template>

<script>
import SearchBox from '@SearchBox'

export default {
  components: { SearchBox }
}
</script>

自定义主题需要手动引入Markdown样式

<Content>中显示的Markdown文件是没有任何样式的,这需要我们自己写一个Markdown样式,但是这样真的太费力气。我们不如去找一份自己喜欢的样式。于是在 typora上找到一份主题 Maize,添加到 style文件夹下并引入后效果对比:

vuepress自定义主题时,帮我们去掉了所有 Markdown相关的样式。所以 Markdown样式需要自己引入。

VuePress  开发个人博客进阶之自定义主题

引入后可以显示样式,确实好看了很多:

VuePress  开发个人博客进阶之自定义主题

如何进行页面路由跳转

关于页面间路由跳转,这个点应该是大多数同学放弃的原因。要踩的坑真的巨大,其实是这样的:在你的文档下 README.md是默认的页面,那么我们就需要思考其他 md文件该如何去显示。

官方的文档中是这样子的:

VuePress  开发个人博客进阶之自定义主题

也就是说当我们想要进入 非README.md的文件时,以 config.md为例,我们需要跳转到 /guide/config.md,前提是你知道 README.md的路径是/guide/。那这就好办了,vuepress对于 $router是支持的,就是说我们可以直接使用 vue的路由跳转,不同是我们不用再去写router.js文件规划路由。

那么用 this.$router.push('/guide/config.md')即可跳转到其他文件的页面。

上述的路径则通过 this.$site.pages可以获取,具体每个页面的内容可以通过 this.$page获取。

由于默认进入的是文件夹下 README.md设置的 layout布局,想要在这个布局里获取其他文件的信息,只能够 Front Matter通过透传,如下所示:

---
layout: RecordLayout
description: '这里有一些技巧,可以帮助你更好地优化 JavaScript 代码,从而提高性能。'
---

非README.md中的 Front Matter输入信息,然后在 README.md设置的布局中的 frontmatter对象拿到信息。

更换 favicon.icon

config.js中添加以下代码,并在 public文件夹中添加 favicon.ico图标,注意这里不要使用其他格式的图片,否则会显示不出来。

head: [
    ['link', { rel: 'shortcut icon', type: "image/x-icon", href: "/favicon.ico" }]
  ]

文章最后更新时间

如果你使用默认主题,你无需安装本插件,因为 VuePress 的 core 中已经包含此插件。这里需要安装:

npm i @vuepress/last-updated
  • 在config.js中添加引入:
module.exports = {
  plugins: ['@vuepress/last-updated']
}

关于最新更新时间插件的实现方式,这里有 传送门

简述 components 和 global-components 的区别

这里简述一下 componentsglobal-components的区别:components所定义的组件仅在 theme下生效,而 global-components下定义的组件不仅局限于 theme而且在 docs目录下的 md文件中可以直接使用。

例如,docs/README.md中:

# Hello VuePress!
<ComponentsTest />         // 不显示
<GlobalComponentsTest />   // 显示

一个项目中多个布局

如果你的首页和博客页想应用不同主题,需要在 theme/layouts下定义多个布局如 HomeLayout.vue,但 Layout.vue必须保留。默认会应用 Layout.vue布局。那如何使用 HomeLayout.vue中的布局呢?

例如,docs/README.md中这样写即可:

---
layout: HomeLayout
---
# Hello VuePress!

如何发布你的主题到npm

发布主题到npm:

  • 将你的主题推送到 github仓库,这里的主题是指 .vuepress文件夹下所有内容需要推送到 github
  • 在 npm 上注册 https://www.npmjs.com/,填入信息并验证邮箱。
  • 进入要发布的项目根目录 .vuepress,初始化为 npm包:
npm init
  • 依次按提示填入包名、版本、描述、github地址、关键字、license等,你的主题命名可以是 vuepress-theme-开头的,这样别人引用时可以简写成 vuepress-theme-后面的字段。
  • 在本地登录你的 npm账号,并输入账号信息:
npm login
  • 将你的包发布,成功的话就可以在npm上搜索到你发布的包了~
npm publish
  • 这样就可以搜索到我的主题 vuepress-theme-mount

    VuePress  开发个人博客进阶之自定义主题

如何使用自定义主题,以 vuepress-theme-mount为例

  • 在本地新建文件夹 vuepress-starter,包含以下目录结构:

    VuePress  开发个人博客进阶之自定义主题

  • 在目录下安装包:

npm init
npm i vuepress-theme-mount
  • 在config.js中输入:
// .vuepress/config.js
module.exports = {
  theme: 'mount'  // or 'vuepress-theme-mount'
}
  • 在 package.json 中加入,并使用命令 vuepress dev docs运行项目,即可打开你的博客。
{
  "scripts": {
    "docs:dev": "vuepress dev docs",
    "docs:build": "vuepress build docs"
  }
}

总结

如果不是像我一样想尝试 vuepress搭建博客,建议还是使用成熟的博客系统,因为 vuepress真的不是很适合用来搭建博客系统,需要踩的坑非常多,比如关于路由跳转的问题文档没有明确说明。如果还有其他关于自定义主题的问题可以留言。

最后,踩坑不易,欢迎鼓励。

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。