WARNING

在开始使用实践之前,你需要注意,自建网站需要一定的相关知识,你可能会遇到一系列的问题,请确保你有独立解决问题的能力。
假如你想修改主题的某些组件或样式,你还需要掌握 Vue.js 的相关知识
虽然如今你可以借助 AI 来辅助完成一些需求,但知其然,知其所以然
是每一个优秀的人都应该具备的基本素养。

TIP

本文使用托管在GitHub仓库的 vivo Sans 字体进行演示

themeConfig.mjs:引用字体

.vitepress\theme\assets\themeConfig.mjs

先预加载CDN:

例如我使用 GitHub 仓库进行字体文件托管

就需要先创建css文件进行引入

css样式如下:

css
/* Regular (400) */
@font-face {
  font-family: 'vivosans';
  src: url('https://cdn.jsdmirror.com/gh/kazukokawagawa/chiyupic@main/fonts/vivosans/vivoSans-Regular.woff2') format('woff2'),
       url('https://cdn.jsdmirror.com/gh/kazukokawagawa/chiyupic@main/fonts/vivosans/vivoSans-Regular.woff') format('woff');
  font-weight: 400;
  font-style: normal;
}

/* Medium (500) */
@font-face {
  font-family: 'vivosans';
  src: url('https://cdn.jsdmirror.com/gh/kazukokawagawa/chiyupic@main/fonts/vivosans/vivoSans-Medium.woff2') format('woff2'),
       url('https://cdn.jsdmirror.com/gh/kazukokawagawa/chiyupic@main/fonts/vivosans/vivoSans-Medium.woff') format('woff');
  font-weight: 500;
  font-style: normal;
}

/* DemiBold (600) */
@font-face {
  font-family: 'vivosans';
  src: url('https://cdn.jsdmirror.com/gh/kazukokawagawa/chiyupic@main/fonts/vivosans/vivoSans-DemiBold.woff2') format('woff2'),
       url('https://cdn.jsdmirror.com/gh/kazukokawagawa/chiyupic@main/fonts/vivosans/vivoSans-DemiBold.woff') format('woff');
  font-weight: 600;
  font-style: normal;
}

/* Bold (700) */
@font-face {
  font-family: 'vivosans';
  src: url('https://cdn.jsdmirror.com/gh/kazukokawagawa/chiyupic@main/fonts/vivosans/vivoSans-Bold.woff2') format('woff2'),
       url('https://cdn.jsdmirror.com/gh/kazukokawagawa/chiyupic@main/fonts/vivosans/vivoSans-Bold.woff') format('woff');
  font-weight: 700;
  font-style: normal;
}

/* ExtraBold (800) */
@font-face {
  font-family: 'vivosans';
  src: url('https://cdn.jsdmirror.com/gh/kazukokawagawa/chiyupic@main/fonts/vivosans/vivoSans-ExtraBold.woff2') format('woff2'),
       url('https://cdn.jsdmirror.com/gh/kazukokawagawa/chiyupic@main/fonts/vivosans/vivoSans-ExtraBold.woff') format('woff');
  font-weight: 800;
  font-style: normal;
}

/* Heavy (900) */
@font-face {
  font-family: 'vivosans';
  src: url('https://cdn.jsdmirror.com/gh/kazukokawagawa/chiyupic@main/fonts/vivosans/vivoSans-Heavy.woff2') format('woff2'),
       url('https://cdn.jsdmirror.com/gh/kazukokawagawa/chiyupic@main/fonts/vivosans/vivoSans-Heavy.woff') format('woff');
  font-weight: 900;
  font-style: normal;
}

.vitepress\theme\assets\themeConfig.mjs 更新内容:

js
      // 预载 CDN
      [
        "link",
        {
          crossorigin: "",
          rel: "preconnect",
          href: "https://s1.hdslb.com",
        },
      ],
      [
        "link",
        {
          crossorigin: "",
          rel: "preconnect",
          href: "https://cdn.jsdmirror.com",
        },
      ],
      // vivo sans
      [
        "link",
        {
          crossorigin: "anonymous",
          rel: "stylesheet",
          href: "https://cdn.jsdmirror.com/gh/kazukokawagawa/chiyupic@main/fonts/vivosans.css",
        },
      ],
      // HarmonyOS font
      [
        "link",
        {
          crossorigin: "anonymous",
          rel: "stylesheet",
          href: "https://s1.hdslb.com/bfs/static/jinkela/long/font/regular.css",
        },
      ],

main.scss:定义字体

.vitepress\theme\style\main.scss

做以下修改:

css
// 字体
html {
  &.vsans {
    --main-font-family: "vivosans", sans-serif;
  }
  &.hmos {
    --main-font-family: "HarmonyOS_Regular", sans-serif;
  }
  p {
  font-weight: 500; /* Medium */
}
  .iconfont {
    font-size: 1rem;
  }
  button {
    font-family: var(--main-font-family);
  }
}

index.js:应用字体

.vitepress\theme\store\index.js

做以下修改:

js
      // 全站字体
      fontFamily: "vsans",

Settings.vue:字体切换显示

.vitepress\theme\components\Settings.vue

做以下修改:

vue
        <div class="set-item">
          <span class="set-label">全站字体</span>
          <div class="set-options">
            <span
              :class="['options', { choose: fontFamily === 'vsans' }]"
              @click="fontFamily = 'vsans'"
            >
              vivo Sans
            </span>
            <span
              :class="['options', { choose: fontFamily === 'hmos' }]"
              @click="fontFamily = 'hmos'"
            >
              HarmonyOS Sans
            </span>
          </div>
        </div>

App.vue:字体切换逻辑

.vitepress\theme\App.vue

做以下修改:

vue
// 切换系统字体样式
const changeSiteFont = () => {
  try {
    const htmlElement = document.documentElement;
    htmlElement.classList.remove("vsans", "hmos");
    htmlElement.classList.add(fontFamily.value);
    htmlElement.style.fontSize = fontSize.value + "px";
  } catch (error) {
    console.error("切换系统字体样式失败", error);
  }
};

相关资源

字体压缩工具: https://github.com/ecomfe/fontmin

https://github.com/ecomfe/fontmin-app/

测试项内容:

移动端默认字体大小16,PC17

js
import { defineStore } from "pinia";
import cursorInit from '@/utils/cursor.js';

let appCursorInstance;
const isMobile = typeof navigator !== 'undefined' && /Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent);

export const mainStore = defineStore("main", {
  state: () => {
    return {
      // 主题类别
      themeType: "auto",
      themeValue: "light",
      // banner
      bannerType: "half",
      // 加载状态
      loadingStatus: true,
      // 滚动高度
      scrollData: {
        height: 0,
        percentage: 0,
        direction: "down",
      },
      // 页脚可见性
      footerIsShow: false,
      // 中控台显示
      controlShow: false,
      // 搜索框显示
      searchShow: false,
      // 个性化配置显示
      showSeetings: false,
      // 播放器数据
      playState: true,
      playerShow: true,
      playerVolume: 0.7,
      playerData: {
        name: "未知曲目",
        artist: "未知艺术家",
      },
      // 移动端菜单显示
      mobileMenuShow: false,
      // 使用自定义右键菜单
      useRightMenu: true,
      // 背景模糊
      backgroundBlur: false,
      // 全站字体
      fontFamily: "vsans",
      // 全站字体大小
      fontSize: isMobile ? 16 : 17,
js
export const initializeCursor = () => {
  if (typeof window === 'undefined' || typeof document === 'undefined') {
    console.warn('initializeCursor skipped in SSR environment.');
    return;
  }

  const store = mainStore();

  if (!appCursorInstance) {
    appCursorInstance = cursorInit();
  }

  if (!appCursorInstance) {
    return;
  }

  store.updateActualThemeValue();
  appCursorInstance.setThemeType(store.themeType);

  // ✅ 新增:设置 html 元素的字体大小
  document.documentElement.style.fontSize = store.fontSize + 'px';

  if (window.matchMedia) {
    const mediaQueryList = window.matchMedia('(prefers-color-scheme: dark)');

    const handleSystemThemeChange = (e) => {
      if (store.themeType === 'auto') {
        store.triggerThemeUpdate();
      }
    };

    if (mediaQueryList.addEventListener) {
      mediaQueryList.addEventListener('change', handleSystemThemeChange);
    } else {
      mediaQueryList.addListener(handleSystemThemeChange);
    }
  }
};
赞赏博主
评论 隐私政策