VuePress is a minimalist static website generation tool for a Vue driven theme system, originally designed to support documentation for Vue subprojects. But now many developers want to use VuePress to build their own blogs, especially vue developers, because VuePress blog topics are based on Vue syntax.

The default theme provided by the official VuePress is very simple and can not meet the needs of developers to customize their blogs. How to write a VuePress theme? I believe that many developers have tried to develop a custom theme, but because vuepress documentation is not sound, many places do not explain, often have to give up.

This article introduces how to develop a VuePress custom theme and how to publish a theme to NPM, helping you to step on the VuePress custom theme development blog pit.

Results show

The above effect is the vuepress-theme-mount style used in my personal blog, which will be improved and opened up in the future. If anyone is interested, here is the github address for the project. There’s a lot of stuff that hasn’t been added yet, so if you want to see it, you can use it as a demo.

start

  1. newvuepressFolder.
  2. Follow the official documentation to install in an existing project.
  3. Configure the project.

As this part of the official document said very clearly, follow the instructions can be completed, do not repeat. After completing the above steps, your directory structure should look like this:

Vuepress ├─ docs │ ├─ readme.md ├─ Node_modules ├─ package-lockCopy the code

Next, run the vuepress dev docs command, showing the page with Hello vuepress and the header section with a search box, as well as the contents of readme.md in the root directory.

Custom themes

Now we’re going to get to the main point: write the theme custom section.

The build directory

Next, we build the directory based on the development theme/directory structure in the official documentation.

  1. Create one in the document root directory.vuepress/themeDirectory, and then create its subdirectories.
Theme ├── global-components // │ ├─ xx.vue.components // │ ├─ xx.vue.components // │ ├─ xx.vue.components // │ ├─ xx.vue.components // Layout components, │ ├── active.vue (active.vue) │ ├─ 374.vue ├── style │ ├── index. Styl │ ├─ clearance ├ ─ enhanceApp.jsCopy the code

After creating the above directory (note that there are no package.json and template folders), run vuepress dev docs and it is blank, indicating that our layout.vue is in effect.

  1. intheme/index.jsAdd:
module.exports = {
   // ...
}
Copy the code

The development layout. Vue

Next, we can develop the layout we want in Layout.vue. The required components are written under theme/ Components and introduced in Layout.vue.

For example, I want my overall layout to be divided into main, Content, and footer sections.

│ ├── header. Vue │ ├─ footer.vueCopy the code

In layout.vue normal introduction:

<template> <div> <Header /> <Content /> <Footer /> </div> </template> <script> import Header from ".. /components/Header" import Footer from ".. /components/Footer" export default { components: { Header, Footer } }; </script>Copy the code

Once you’ve written it, run NPM run docs:dev to see your page. Start writing your own blog topic just as you would a normal Vue project.

Integrate third-party UIs into the theme

Here to develop the top navigation bar as an example, demonstrate the installation and use of third-party library Element-UI.

CD Go to the theme directory and run the installation command: NPM I element-ui -s.

To install babel-plugin-component, run the NPM install babel-plugin-component -d command.

Next, create.babelrc in the Theme directory and change it to:

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

Next, if you only want to introduce some components, such as Menu, then you need to write the following in enhanceApp.js:

import { Menu, Submenu, MenuItem, MenuItemGroup } from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Export default ({Vue, // Vue constructor options that VuePress is using, // append some options to the root instance router, Use (Menu) vue.use (Submenu) vue.use (MenuItem) vue.use (MenuItemGroup)}Copy the code

Once the above steps are installed, you can use them in your components in the same way as a normal VUE project.

Use the vuepress official plugin

Here to develop the top navigation bar as an example, demonstrate the installation of the plug-in search box and use. The installation of the plug-in is clearly explained in the official documentation, so here is a demonstration.

The installation

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

Configure the plug-in

In the vuepress/config. In js:

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

use

The search plug-in automatically injects the @searchBox webPack alias that points to the search component. You can use it directly in the Layout component:

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

<script>
import SearchBox from '@SearchBox'

export default {
  components: { SearchBox }
}
</script>
Copy the code

Custom themes require manual introduction of the Markdown style

The Markdown file shown in

has no style, which requires us to write our own Markdown style, which is too much effort. Why don’t we go find something we like. Then find a copy of Maize on Typora, add it to the style folder and compare the results:

When vuepress customized the theme, it helped us remove all the Markdown related styles. So the Markdown style needs to be introduced itself.

After the introduction of the style can be displayed, it really looks much better:

How do I redirect a page

As for the interpage route jump, this point should be the reason most students give up. That’s a big hole to tread, but here’s the thing: readme. md is the default page under your document, so we need to think about how other MD files are displayed.

The official document looks like this:

That is, when we want to go to a file that is not readme.md, for example config.md, we need to go to /guide/config.md, provided that you know that the path to readme.md is /guide/. Vuepress supports $router, which means we can use vue’s route jump directly. The difference is that we don’t have to write router.js to plan the route.

$router.push(‘/guide/config.md’)

$site.pages. The contents of each page can be obtained by this.$page.

As the default entry is the layout set by readme. md in the folder, if you want to get the information of other files in this layout, only Front Matter can be transparently transmitted, as shown below:

-- Layout: RecordLayout Description: 'Here are some tips to help you optimize your JavaScript code for better performance. '-- -- --Copy the code

Enter the information in Front Matter in non-readme.md, and then get the information in the FrontMatter object in the layout set by readme.md.

replacefavicon.icon

Add the following code to config.js and add the favicon.ico icon to the public folder. Be careful not to use any other image format here, otherwise it will not be displayed.


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

This article was last updated

If you are using the default theme, you do not need to install this plugin because it is already included in the VuePress core. Here you need to install:

npm i @vuepress/last-updated
Copy the code
  • Add import to config.js:
module.exports = {
  plugins: ['@vuepress/last-updated']
}
Copy the code

There is a portal to how the latest update time plugin is implemented.

Describe the difference between components and global-Components

Here are the differences between components and global-Components: Components defined by components are valid only in the theme, while global-Components are not limited to the theme and can be directly used in the MD file in the docs directory.

For example, in docs/ readme.md:

# Hello VuePress! <ComponentsTest /> // Do not display <GlobalComponentsTest /> // DisplayCopy the code

Multiple layouts in a project

If you want to use different themes on your home and blog pages, define multiple layouts under theme/layouts, such as Homelayout. vue, but Layout. The layout. vue Layout is applied by default. So how do you use the layout in homelayout.vue?

For example, docs/ readme.md might look like this:

---
layout: HomeLayout
---
# Hello VuePress!
Copy the code

How to publish your topic to NPM

Post a topic to NPM:

  • Push your theme togithubWarehouse, the subject here is.vuepressAll contents in the folder need to be pushed togithub.
  • Register with NPMhttps://www.npmjs.com/, fill in the information and verify the mailbox.
  • Go to the root directory of the project you want to publish.vuepressIs initialized tonpmPackage:
npm init
Copy the code
  • Fill in the package name, version, description,githubAddress, keywords, license, etc. Your topic name can bevuepress-theme-At the beginning, so that when people quote it, they can abbreviate itvuepress-theme-The following fields.
  • Log in locally to yournpmAccount number and enter the account information:
npm login
Copy the code
  • Publish your package. If successful, you can search NPM for your published package
npm publish
Copy the code
  • So you can search for my topicvuepress-theme-mount

How to use custom themes tovuepress-theme-mountAs an example

  • Create a folder locallyvuepress-starterContains the following directory structure:

  • Install the package in the following directory:
npm init
npm i vuepress-theme-mount
Copy the code
  • In config.js, enter:
// .vuepress/config.js
module.exports = {
  theme: 'mount'  // or 'vuepress-theme-mount'
}
Copy the code
  • Json, and use the commandvuepress dev docsRun the project to open your blog.
{
  "scripts": {
    "docs:dev": "vuepress dev docs",
    "docs:build": "vuepress build docs"
  }
}
Copy the code

conclusion

If you don’t want to try to build a blog with Vuepress like I do, it is recommended to use a mature blog system, because vuepress is really not very suitable for building a blog system, there are many holes to step on, such as the problem of routing jump is not clearly stated in the document. If you have any more questions about custom topics, please leave a comment.

Finally, stepping pit is not easy, welcome encouragement.