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(() =>