跳转到内容

VitePress用法与配置

一些用法笔记与使用的配置记录。

文档与参考:

字体

博客webfont字体配置:

css
/*
字体配置说明
主字体设置:
- 英文:Inter (现代无衬线字体,优先级最高,非等宽)
- 中文:Noto Sans SC/TC (谷歌开源中文字体,优先级次之)
- 系统字体回退:按优先级依次为 PingFang SC > Microsoft YaHei > Hiragino Sans GB > WenQuanYMicro Hei

字体优先级原理:
- 英文文本会优先使用字体列表中的第一个支持拉丁字符的字体(Inter)
- 中文文本会使用第一个支持中文字符的字体(Noto Sans SC/TC)
- 代码块通过额外的 CSS 规则确保使用 JetBrains Mono

原来的字体配置,这种缺点是字体太大了,为了减少体积,还是使用webfont:
@font-face {
  font-family: "customFont";
  src: url("/xxx.woff2") format("woff2");
  font-display: swap;
}

一些尝试过的字体:
@import url("https://fonts.font.im/css2?family=Inter:wght@400;700&display=swap");
@import url("https://fonts.font.im/css2?family=Noto+Sans+TC:wght@400;700&display=swap");
@import url("https://fonts.font.im/css2?family=JetBrains+Mono:wght@400;700&display=swap");
@import url("https://fonts.font.im/css2?family=LXGW+WenKai+TC:wght@400;700&display=swap");
@import url("https://fonts.font.im/css2?family=Chiron+Sung+HK:wght@400;700&display=swap");
@import url("https://fonts.font.im/css2?family=M+PLUS+1p:wght@400;500;700&display=swap");
@import url("https://cdnjs-jp.loli.net/ajax/libs/lxgw-wenkai-screen-webfont/1.7.0/lxgwwenkaiscreen.css");

使用最广泛的webfont:https: //fonts.google.com/
中文版:https: //www.googlefonts.cn/
中文版引用:https: //fonts.font.im/
*/

/* 英文主字体 */
@import url("https://fonts.font.im/css2?family=Inter:wght@400;700&display=swap");
/* 中文主字体 */
@import url("https://fonts.font.im/css2?family=Noto+Sans+SC:wght@400;500;700&display=swap");
/* 代码等宽字体 */
@import url("https://fonts.font.im/css2?family=JetBrains+Mono:wght@400;700&display=swap");

关于字重:

英文和代码用400和700就够了,中文的话需要使用多一个500,介于400和700之间,左右侧边栏的字体相对小,使用500字重效果好点,正文使用400,加粗和正文标题使用700,视觉效果相对更好。

字体使用总结:

Noto Sans(思源黑体)是综合体验非常好的一款开源字体,可以很方便使用webfont。

其他优秀开源的中文字体收集:

霞鹜系列是非常出色的开源字体,实际体验下来,霞骛新晰黑的效果非常好,在Windows低分辨率下也有不错的效果;但是霞鹜文楷在Windows低分辨率下表现却不行。新晰黑目前暂时找不到webfont和屏幕阅读版本,如果以后有的话,可以考虑替换思源黑体。综合来看,目前思源黑体还是第一选择的webfont。

提示框

> [!NOTE] 提示
> 强调用户在快速浏览文档时也不应忽略的重要信息。

> [!TIP] 建议
> 有助于用户更顺利达成目标的建议性信息。

> [!IMPORTANT] 重要
> 对用户达成目标至关重要的信息。

> [!WARNING] 警告
> 因为可能存在风险,所以需要用户立即关注的关键内容。

> [!CAUTION] 危险
> 行为可能带来的负面影响。

类似于vitepress自带:

::: info
This is an info box.
:::

::: tip
This is a tip.
:::

::: warning
This is a warning.
:::

::: danger
This is a dangerous warning.
:::

::: details 点我查看
This is a details block.
:::

结果展示:

提示

强调用户在快速浏览文档时也不应忽略的重要信息。

建议

有助于用户更顺利达成目标的建议性信息。

重要

对用户达成目标至关重要的信息。

警告

因为可能存在风险,所以需要用户立即关注的关键内容。

危险

行为可能带来的负面影响。

点我查看

This is a details block.

代码块组标题

代码块组语法:

markdown
::: code-group
`ˋ`sh [pnpm]
#查询pnpm版本
pnpm -v
`ˋ`
`ˋ`sh [yarn]
#查询yarn版本
yarn -v
`ˋ`
:::

结果展示:

sh
#查询pnpm版本
pnpm -v
sh
#查询yarn版本
yarn -v

利用代码块组的语法和效果,我们也可以为单个代码块显示代码块标题或者代码文件名称及文件路径。

markdown
::: code-group
`ˋ`vue [post/markdown-examples.vue]
<template>

  <div>{{ text }}</div>
</template>
`ˋ`
:::

结果展示:

vue
<template>
    <div>{{ text }}</div>
</template>

代码嵌套

可以使用更多的反引号来展示包含代码块的代码。例如:

markdown
````markdown
```js
export default {
    data() {
        return {
            title: "笔记",
        };
    },
};
```
````

行高亮与聚焦

text
在代码块的语言名词之后,添加 {n},来高亮某一行,连续行用 - ,不连续行用 ,

或者在某一行后面添加 // [!code highlight] 注释实现行高亮。

在某一行上添加 // [!code focus] 注释将聚焦它并模糊代码的其他部分。

此外,可以使用 // [!code focus:lines] 定义要聚焦的行数。

在某一行添加 // [!code --] 或 // [!code ++] 注释将会为该行创建 diff,同时保留代码块的颜色。

在某一行添加 // [!code warning] 或 // [!code error] 注释将会为该行相应的着色

部分汉化

vitepress的汉化原生做得不好,这里只简单配置一下中文,主要的一些配置有:

js
themeConfig : {
        // siteTitle : false, // 隐藏标题
        footer : {
            message : "", //   message: '基于 MIT 许可发布',
            copyright :
                `版权所有 © 2024 - ${new Date().getFullYear()} unixtea.com`,
        },
        // 设置文章自动生成的目录 层级
        outline : {label : "当前页大纲", level : [ 2, 3 ]},
        docFooter : {prev : "上一页", next : "下一页"},
        lastUpdated : {
            text : "最后更新于",
            formatOptions : {dateStyle : "short", timeStyle : "medium"},
        },
        langMenuLabel : "多语言",
        // returnToTopLabel : "回到顶部",
        sidebarMenuLabel : "菜单",
        darkModeSwitchLabel : "主题",
        lightModeSwitchTitle : "切换到浅色模式",
        darkModeSwitchTitle : "切换到深色模式",
        skipToContentLabel : "跳转到内容",
        search : search,
        nav : nav,
        // 站点地图 VitePress 提供开箱即用的配置,由 sitemap
        // 模块提供支持,为站点生成 sitemap.xml 文件
        sitemap : {
            hostname : 'https://blog.unixtea.com',
        }
    }

配置搜索

自带的默认搜索功能比较弱,更换更好用的algolia:

js
export default {
  provider: "algolia",
  options: {
    appId: "4DSDG361J3",
    apiKey: "ff55039fa6275cd86e5f17c0eacbae56",
    indexName: "unixtea",
    insights: true,
    placeholder: "请输入关键词",
    translations: {
      button: { buttonText: "搜索文档", buttonAriaLabel: "搜索文档" },
      modal: {
        noResultsText: "无法找到相关结果",
        resetButtonTitle: "清除查询条件",
        footer: {
          selectText: "回车进入当前选择结果",
          navigateText: "切换",
          closeText: "关闭",
        },
      },
      searchBox: {
        resetButtonTitle: "清除搜索内容",
        resetButtonAriaLabel: "清除搜索内容",
        cancelButtonText: "取消",
        cancelButtonAriaLabel: "取消",
      },
      recentSearches: {
        noRecentSearchesText: "暂无搜索记录",
        recentSearchesTitle: "最近搜索",
        removeRecentSearchButtonTitle: "删除这条记录",
        removeAllRecentSearchesButtonTitle: "清空所有搜索记录",
      },
    },
  },
};

注意事项:

Algolia 后台的数据是以 lang:en-US 的形式存储的,而 VitePress 搜索的时候是以 lang:zh-CN 的形式搜索的,所以 Algolia 后台没有对应的数据,所以搜索不到数据。反之亦然。所以在切换lang之后进行搜索,会搜索不到结果,解决办法就是手动进行Algolia索引。

参考这里

github与vercel

建立一个私有的github仓库,然后clone到本地,把项目上传到仓库中。

github配置vercel自动构建部署,连接到仓库后,直接确定即可,以后每次提交到仓库,就会触发vercel自动构建部署。

配置cloudflare自动解析域名,把域名指向vercel的地址即可。

图片贴图相关

图片上传使用vscode插件 Paste Image来实现,直接张贴剪切板到指定的图片目录,方便快捷。

图片点击放大

bash
npm i -D medium-zoom

配置:

js
export default {
    extends: DefaultTheme,
    setup() {
        const route = useRoute();
        const initZoom = () => {
            // mediumZoom('[data-zoomable]', { background: 'var(--vp-c-bg)' }); // 默认
            mediumZoom(".main img", { background: "var(--vp-c-bg)" }); // 不显式添加{data-zoomable}的情况下为所有图像启用此功能
        };
        onMounted(() => {
            initZoom();
        });
        watch(
            () => route.path,
            () => nextTick(() => initZoom()),
        );
    },
    Layout: () => {
        return h(DefaultTheme.Layout, null, {
            // https://vitepress.dev/guide/extending-default-theme#layout-slots
        });
    },
    enhanceApp({ app, router, siteData }) {
        // ...
    },
};

css配置:

css
/* 图片放大缩小 */
.medium-zoom-overlay {
    z-index: 30;
}
.medium-zoom-image {
    z-index: 999 !important; /* 给的值是21,但是实测盖不住,直接999 */
}

阅读布局切换

默认是居中布局,可以添加布局进行切换。使用插件:

bash
npm i @nolebase/vitepress-plugin-enhanced-readabilities -D

项目地址:https://github.com/nolebase/integrations/blob/main/packages/vitepress-plugin-enhanced-readabilities/README.md

文档地址:https://nolebase-integrations.ayaka.io/pages/en/integrations/vitepress-plugin-enhanced-readabilities/

主要配置theme/index.js:

js
import DefaultTheme from "vitepress/theme";
import mediumZoom from "medium-zoom";
import { h, onMounted, watch, nextTick } from "vue";
import { useRoute } from "vitepress";
// import googleAnalytics from 'vitepress-plugin-google-analytics';
// import { Analytics } from '@vercel/analytics/vue';
// 导入增强阅读布局菜单
import {
  NolebaseEnhancedReadabilitiesMenu,
  NolebaseEnhancedReadabilitiesScreenMenu,
  InjectionKey,
} from "@nolebase/vitepress-plugin-enhanced-readabilities/client";
import "@nolebase/vitepress-plugin-enhanced-readabilities/client/style.css";
// 导入回到顶部组件
import BackToTop from "./components/BackToTop.vue";
// vitepress 自带的样式
import "./style.css";
// 自定义样式
import "./custom.css";
// 主题:https://github.com/catppuccin/vitepress
export default {
  extends: DefaultTheme,
  setup() {
    const route = useRoute();
    const initZoom = () => {
      // 默认 mediumZoom('[data-zoomable]', { background: 'var(--vp-c-bg)' });
      // 不显式添加{data-zoomable}的情况下为所有图像启用此功能
      mediumZoom(".main img", { background: "var(--vp-c-bg)" });
    };
    onMounted(() => {
      initZoom();
      // 添加 Umami 统计代码
      // const umamiScript = document.createElement('script');
      // umamiScript.defer = true;
      // umamiScript.src = 'https://cloud.umami.is/script.js';
      // umamiScript.setAttribute('data-website-id', '4be34bf4-3089-4f18-b1a0-fe2bdd6544e7');
      // document.head.appendChild(umamiScript);

      // 添加 Cloudflare Web Analytics 统计代码
      //   const cfScript = document.createElement('script');
      //   cfScript.defer = true;
      //   cfScript.src = 'https://static.cloudflareinsights.com/beacon.min.js';
      //   cfScript.setAttribute('data-cf-beacon', '{"token": "fe3d85097fcd4dc1add0d87b36e1419b"}');
      //   document.head.appendChild(cfScript);
    });
    watch(
      () => route.path,
      () => nextTick(() => initZoom())
    );
  },
  Layout: () => {
    return h(DefaultTheme.Layout, null, {
      "nav-bar-content-after": () => h(NolebaseEnhancedReadabilitiesMenu),
      "nav-screen-content-after": () => h(NolebaseEnhancedReadabilitiesScreenMenu),
      // 添加回到顶部组件
      "layout-bottom": () => [
        h(BackToTop),
        // h(Analytics)
      ],
    });
  },
  enhanceApp({ app, router, siteData }) {
    // googleAnalytics({
    //   id: 'G-XN13TDJK5X'
    // })

    app.provide(InjectionKey, {
      locales: { // i18n //
        'zh-CN': { // configure for Simplified Chinese //
          title: {
            title: '阅读增强插件',
          }
        },
        'en': { // configure for English //
          title: {
            title: 'Enhanced Readabilities Plugin',
          }
        }
      }
    });

  },
};

在移动端隐藏阅读布局切换功能:

css
@media (max-width: 768px) {
  div[class*='VPNolebaseEnhancedReadabilities'] {
    display: none !important;
  }
}

Emoji表情使用

Vitepress 内置了常用的表情,供我们使用。

查看所有Vitepress支持的表情,或者查看表情包大全

排版更好看的:

如果找不到可以到emojipedia在线复制后粘贴到编辑器即可。

md
:eight: :seven:

效果展示:

8️⃣ 7️⃣

注意:在不同设备上,emoji表情渲染结果很可能不一样,比如在mac和windows上的chrome浏览器渲染结果差别就很大,所以尽量慎用emoji,如果一定要用,请确保在所有设备上都是预期的效果。

抽离配置目录

默认的配置,所有的都堆叠都一起,这里单独抽离出nav、search等看起来比较复杂的配置,单独配置,这样看起来比较简洁。

抽离配置的时候,需要配置package.json的配置,添加type:

json
{
  "devDependencies": {
    "@nolebase/ui": "^2.17.2",
    "@nolebase/vitepress-plugin-enhanced-readabilities": "^2.17.2",
    "@vueuse/core": "^12.8.2",
    "@vueuse/shared": "^12.8.2",
    "medium-zoom": "^1.1.0",
    "vitepress": "^1.6.3",
    "vue": "^3.5.16"
  },
  "scripts": {
    "dev": "vitepress dev docs --port 8888",
    "dev:lint": "markdownlint **/*.md -f && npm run dev",
    "build": "vitepress build docs",
    "pre": "vitepress preview docs"
  },
  "type": "module",
  "license": "MIT",
  "dependencies": {
    "@vue/devtools-kit": "^7.7.6",
    "@vue/devtools-api": "^7.7.6",
    "@vue/devtools-shared": "^7.7.6",
    "birpc": "^2.4.0",
    "hookable": "^5.5.3",
    "opencclint-config": "^0.0.6",
    "perfect-debounce": "^1.0.0",
    "vue-router": "^4.5.1"
  }
}