From 3e3e8899d5eccc67b031b7357fa28189eae543cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=B4=AE=E7=94=9F=EF=BC=88=E5=AD=90=E8=99=9A=EF=BC=89?=
<2234839456@qq.com>
Date: Fri, 31 Jul 2026 00:03:33 +0800
Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=AD=97=E4=BD=93?=
=?UTF-8?q?=E8=AF=A6=E6=83=85=E9=A1=B5=E5=AD=97=E4=BD=93=E6=9C=AA=E5=BA=94?=
=?UTF-8?q?=E7=94=A8=E2=80=94=E2=80=94@font-face=20=E6=9B=BF=E4=BB=A3=20li?=
=?UTF-8?q?nk=20stylesheet?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
根因:API 返回二进制 woff2 字体文件,但前端用
引用它,浏览器无法将 woff2 二进制作为 CSS 解析,导致字体完全未加载。
修复:
- 用 watchEffect + document.createElement('style') 动态注入 @font-face
声明,通过 src: url(...) 引用 API 返回的 woff2 二进制
- 修正 usageCode 示例代码,展示正确的 @font-face 用法
- 添加 SSG/SSR 守卫(typeof document === 'undefined' 跳过)
验证:document.fonts.check() 返回 true,字体 status 为 loaded
---
src/pages/FontDetail.vue | 44 ++++++++++++++++++++++++++++++----------
1 file changed, 33 insertions(+), 11 deletions(-)
diff --git a/src/pages/FontDetail.vue b/src/pages/FontDetail.vue
index eaeb867..b5b3078 100644
--- a/src/pages/FontDetail.vue
+++ b/src/pages/FontDetail.vue
@@ -6,7 +6,7 @@
* 产出完整 HTML 模板(title/meta/body 全含占位符)。
* 后端收到 /fonts/实际字体名 时读取模板做字符串替换返回。
*/
-import { ref, computed, onMounted } from "vue";
+import { ref, computed, onMounted, watchEffect, onUnmounted } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useHead } from "@unhead/vue";
import { fetchFonts, fetchFontMeta } from "../api";
@@ -100,12 +100,39 @@ const allPreviewText = computed(() => {
return [c.previewText ?? "", c.charsetPreview ?? ""].join("");
});
+/** 子集字体 URL(合并所有预览文字) */
+const subsetFontUrl = computed(() => {
+ if (!allPreviewText.value) return "";
+ return `${origin.value}/api?font=${encodeURIComponent(fontName.value)}&text=${encodeURIComponent(allPreviewText.value)}&outType=woff2`;
+});
+
+/** 动态注入 @font-face —— API 返回二进制 woff2,需用 @font-face 引入而非 */
+let injectedStyle: HTMLStyleElement | null = null;
+watchEffect(() => {
+ /** SSG/SSR 阶段没有 document */
+ if (typeof document === "undefined") return;
+ const css = subsetFontUrl.value
+ ? `@font-face { font-family: "${fontName.value}"; src: url("${subsetFontUrl.value}") format("woff2"); }`
+ : "";
+ if (!css) return;
+ if (!injectedStyle) {
+ injectedStyle = document.createElement("style");
+ document.head.appendChild(injectedStyle);
+ }
+ injectedStyle.textContent = css;
+});
+onUnmounted(() => {
+ injectedStyle?.remove();
+ injectedStyle = null;
+});
+
/** 使用方法示例代码(动态拼接 origin + fontName) */
const usageCode = computed(() =>
- `
-
-`
);
@@ -113,12 +140,7 @@ const usageCode = computed(() =>