发布于

置顶 Welcome

vitepress-theme-vuejsblog 是一个仅为博客设计的主题。它并非为文档设计,没有太多的自定义选项,但足够我使用。或许你也会喜欢。

本文将介绍主题的用法。

TIP

主题外观灵感来自于 https://blog.vuejs.org ,其源码位于 Github 。


快速开始 ​

首先,通过脚手架应用快速初始化。

--yes 参数会为所有参数应用默认值。

bash
pnpm dlx vitepress-theme-vuejsblog init my-blog --yes
cd my-blog
pnpm install
pnpm dev
bash
npx vitepress-theme-vuejsblog init my-blog --yes
cd my-blog
npm install
npm run dev

现在应该可以通过 http://localhost:5173 访问到开发服务器。

Markdown 拓展 ​

本主题支持全部 Vitepress 默认主题的markdown 拓展 用法。

还支持部分来自 Vuepress Theme Hope 的拓展用法:

主题配置 ​

TIP

建议在修改主题配置文件后重启开发服务器。

本主题的配置文件位于 ./vitepress/config.ts。 我们将在后文逐步介绍主题配置。

.vitepress/config.ts
ts
export default defineConfig<ThemeConfig>({
  // ...
  themeConfig: {
    blog: {
      title: 'My Blog',
      author: { name: 'Your Name' },
      logo: '/logo.svg',
      favicon: '/logo.svg',
      nav: [{ text: 'About', link: '/about' }],
      footer: { text: '© 2026 My Blog' },
      feed: { language: 'en' }
    }
  }
})

网站配置 ​

网站标题与描述 ​

WARNING

始终需要正确设置 themeConfig.title 与 themeConfig.description 。

通过 themeConfig.title 与 themeConfig.description 字段设置网站的标题与描述。

.vitepress/config.ts
ts
export default defineConfig<ThemeConfig>({
  // ...
  themeConfig: {
    title: 'The Website Title',
    description: 'The description of website',
    blog: {
      siteTitle: 'Another Title',
      siteSubtext: 'Another <a href="/">Description</a>' // siteSubtext 支持 HTML
    }
  }
})

首页 Hero ​

通过 themeConfig.blog.hero 字段设置首页 Hero 。

.vitepress/config.ts
ts
export default defineConfig<ThemeConfig>({
  // ...
  themeConfig: {
    title: 'The Website Title',
    description: 'The description of website',
    blog: {
      hero: {
        title: 'Vitepress Theme Vuejs Blog',
        avatar: false,
        // subtext 支持 HTML
        subtext:
          "This is not the official <a href='https://vuejs.org'>Vue.js</a> website. We just cite <a href='https://blog.vuejs.org'>blogs</a> to verify rendering."
      }
    }
  }
})

网站语言 ​

.vitepress/config.ts
ts

export default defineConfig<ThemeConfig>({
  // ...
  themeConfig: {
    lang: 'zh-CN' // 网站语言
    blog: {
      locale: 'en-US' // 日期渲染格式
    }
  }
})

文章位置 ​

默认情况下,主题将会读取 posts/ 目录下所有 *.md 文件。

可以通过修改 themeConfig.blog.posts 来调整目录结构。

.vitepress/config.ts
ts
export default defineConfig<ThemeConfig>({
  // ...
  themeConfig: {
    blog: {
      // ...
      posts: ['posts/*.md', 'docs/**/*.md']
    }
  }
})

调整之后,主题会同时读取 posts/下的全部 *.md 文件,并递归读取 docs/ 目录下所有 *.md 文件。

首页顶栏 ​

本站的顶栏设置。

vitepress/config.ts
ts
export default defineConfig<ThemeConfig>({
  // ...
  themeConfig: {
    blog: {
      nav: [
        {
          text: 'Github',
          icon: `<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
                  <path d="M0 0h24v24H0z" fill="none" />
                  <path fill="currentColor" d="M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
                </svg>`,
          link: 'https://github.com/weinibuliu/vitepress-theme-vuejsblog'
        }
      ]
    }
  }
})

外链标记 ​

TIP

  • footer.text 与 hero.subtext 其中的外链不会被标记。如有需要,请自己添加类名。

主题会自动为外链统一打上 vp-blog-external-link 类名,并在默认情况下显示小箭头。

通过 themeConfig.blog.externalArrow 关闭箭头显示。

.vitepress/config.ts
ts
export default defineConfig<ThemeConfig>({
  // ...
  themeConfig: {
    blog: {
      externalArrow: true // 默认,三个区域都绘制
      // externalArrow: false, // 全部关闭
      // externalArrow: { nav: false, content: false }, // 只关闭部分区域
    }
  }
})

处理外链跳转 ​

.vitepress/theme/index.ts
ts
import Theme from 'vitepress-theme-vuejsblog'

export default {
  extends: Theme,
  enhanceApp() {
    if (import.meta.env.SSR) return

    document.addEventListener('click', (event) => {
      const target = event.target as Element | null
      const link = target?.closest('a.vp-blog-external-link')
      if (!link) return

      const message = `你即将离开本站,前往 ${link.getAttribute('href')}`
      if (window.confirm(message)) return
      event.preventDefault()
    })
  }
}

TOC ​

主题默认会为所有文章生成 TOC 侧栏,可以通过 themeConfig.blog.toc: false 禁用。

.vitepress/config.ts
ts

export default defineConfig<ThemeConfig>({
  // ...
  themeConfig: {
    blog: {
      toc: false
  }
})

也可以在 frontmatter 中单独启用/禁用某篇文章的 TOC 。

本站便是如此设置的

md
---
# ...
toc: true
---

置顶文章 ​

md
---
pin: true
---

在 frontmatter 中使用 pin 字段来置顶文章。支持传入 number | true。

传入 true 时,相当于 pin: 0。存在多个置顶文章时,按优先级升序排列。

如果多个文章使用相同的优先级,构建时将会报错。请为每篇文章分配不同的优先级。

隐藏/排除文章 ​

见 Not Ready for Production? 。

博客作者 ​

主题提供了 themeConfig.blog.author 字段以设置主题层面的默认作者。

文章作者信息的优先级为: 文件级作者定义 > 域级作者定义 > 主题级作者定义

.vitepress/config.ts
ts
export default defineConfig<ThemeConfig>({
  // ...
  themeConfig: {
    blog: {
      // ...
      author: {
        name: 'weinibuliu',
        gravatar:
          '2b9643e3e2b5062b1bf581ed52213805389cbd628f87967816dd6a8d3c0bf951',
        github: 'https://github.com/weinibuliu'
      }
      // 当然,也可以只提供一个字符串
      // author: 'Example 1'
    }
  }
})

始终可以在文章的 frontmatter 中覆盖主题层面的默认值。

提供一个字符串:

md
---
author: Example 3
---

或者,提供一个对象:

md
---
- name: weinibuliu
  gravatar: 2b9643e3e2b5062b1bf581ed52213805389cbd628f87967816dd6a8d3c0bf951
  github: https://github.com/weinibuliu
---

按域定义作者 ​

可以按文件目录定义该域下的作者。被成功匹配的文章将使用对应的域级作者定义而非主题级作者定义。

需要注意的是:

  • 域定义不支持通配符
  • 始终尝试匹配更精确(更长)的路径而非按数组顺序匹配

以下配置的效果可参见这篇文章

.vitepress/config.ts
ts
export default defineConfig<ThemeConfig>({
  // ...
  themeConfig: {
    blog: {
      // ...
      authorScopes: {
        'docs/': {
          name: 'weinibuliu',
          gravatar:
            '2b9643e3e2b5062b1bf581ed52213805389cbd628f87967816dd6a8d3c0bf951',
          github: 'https://github.com/weinibuliu'
        },
        'docs/en-us': {
          name: 'WEINIBULIU',
          gravatar:
            '2b9643e3e2b5062b1bf581ed52213805389cbd628f87967816dd6a8d3c0bf951',
          github: 'https://github.com/weinibuliu',
          x: 'https://x.com/example',
          facebook: 'https://facebook.com/example',
          instagram: 'https://instagram.com/example'
        }
      }
    }
  }
})

合著 ​

可以为 author 字段提供一个数组表示合著:

本文就是如此设置的

md
---
# ...
author:
  - name: weinibuliu
    gravatar: 2b9643e3e2b5062b1bf581ed52213805389cbd628f87967816dd6a8d3c0bf951
    github: https://github.com/weinibuliu
  - name: Example 1
  - name: Example 2
    x: https://x.com/example
    github: https://github.com/example
    mail: example@example.com
    customSocial:
      icon:
        svg: >-
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><circle cx="5" cy="19" r="3"/><path d="M2 10v4c4.4 0 8 3.6 8 8h4c0-6.6-5.4-12-12-12Z"/><path d="M2 3v4c8.3 0 15 6.7 15 15h4C21 11.6 12.4 3 2 3Z"/></svg>
      label: RSS
      link: /feed.rss
---

作者头像 ​

主题支持使用完整 URL(author.avatar) 和 gravatar 标识符(author.gravatar) 提供作者头像。

author.avatar 优先级大于 author.gravatar

md
---
# ...
- author:
    - name: weinibuliu
      gravatar: 2b9643e3e2b5062b1bf581ed52213805389cbd628f87967816dd6a8d3c0bf951
    - name: Anyoumous
      avatar: https://gravatar.com/avatar
      gravatar: 2b9643e3e2b5062b1bf581ed52213805389cbd628f87967816dd6a8d3c0bf951
---

这将会渲染为: