mirror of
https://github.com/2234839/web-font.git
synced 2026-09-04 23:02:27 +08:00
fix: 修复字体详情页字体未应用——@font-face 替代 link stylesheet
根因:API 返回二进制 woff2 字体文件,但前端用 <link rel="stylesheet">
引用它,浏览器无法将 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
This commit is contained in:
parent
6421e7d059
commit
3e3e8899d5
@ -6,7 +6,7 @@
|
|||||||
* 产出完整 HTML 模板(title/meta/body 全含占位符)。
|
* 产出完整 HTML 模板(title/meta/body 全含占位符)。
|
||||||
* 后端收到 /fonts/实际字体名 时读取模板做字符串替换返回。
|
* 后端收到 /fonts/实际字体名 时读取模板做字符串替换返回。
|
||||||
*/
|
*/
|
||||||
import { ref, computed, onMounted } from "vue";
|
import { ref, computed, onMounted, watchEffect, onUnmounted } from "vue";
|
||||||
import { useRoute, useRouter } from "vue-router";
|
import { useRoute, useRouter } from "vue-router";
|
||||||
import { useHead } from "@unhead/vue";
|
import { useHead } from "@unhead/vue";
|
||||||
import { fetchFonts, fetchFontMeta } from "../api";
|
import { fetchFonts, fetchFontMeta } from "../api";
|
||||||
@ -100,12 +100,39 @@ const allPreviewText = computed(() => {
|
|||||||
return [c.previewText ?? "", c.charsetPreview ?? ""].join("");
|
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 引入而非 <link rel=stylesheet> */
|
||||||
|
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) */
|
/** 使用方法示例代码(动态拼接 origin + fontName) */
|
||||||
const usageCode = computed(() =>
|
const usageCode = computed(() =>
|
||||||
`<link rel="stylesheet"
|
`<style>
|
||||||
href="${origin.value}/api?font=${fontName.value}&text=你的文字&outType=woff2">
|
@font-face {
|
||||||
|
font-family: "${fontName.value}";
|
||||||
<style>
|
src: url("${origin.value}/api?font=${fontName.value}&text=你的文字&outType=woff2") format("woff2");
|
||||||
|
}
|
||||||
.my-title { font-family: "${fontName.value}"; }
|
.my-title { font-family: "${fontName.value}"; }
|
||||||
</style>`
|
</style>`
|
||||||
);
|
);
|
||||||
@ -113,12 +140,7 @@ const usageCode = computed(() =>
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div style="min-height: 100vh; background: #fafafa">
|
<div style="min-height: 100vh; background: #fafafa">
|
||||||
<!-- 字体加载:合并所有预览文字请求字体子集 -->
|
<!-- 字体加载:通过 watchEffect 注入 @font-face(见 script 部分) -->
|
||||||
<link
|
|
||||||
v-if="allPreviewText"
|
|
||||||
rel="stylesheet"
|
|
||||||
:href="`${origin}/api?font=${fontName}&text=${encodeURIComponent(allPreviewText)}&outType=woff2`"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 顶部导航 -->
|
<!-- 顶部导航 -->
|
||||||
<div
|
<div
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user