本次提交主要进行了以下修改: 1. 在nuxt.config.ts中调整了预渲染路由的配置方式,使用扩展运算符以提高可读性。 2. 在README.md中新增了字体本地化指南,详细说明了如何更新和使用本地字体。 3. 在styles.css中移除了Google字体的直接引用,改为使用本地化的字体文件,提升性能。 4. 新增了多个字体文件(M PLUS 1p和Roboto)的本地化支持。 5. 在多个组件中将默认语言设置为中文,以符合项目需求。 这些改动旨在提升代码的可维护性和性能,同时增强用户体验。master
@@ -73,3 +73,26 @@ bun run preview | |||
``` | |||
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. | |||
## 字体本地化指南 | |||
本项目使用了以下Google字体,并已进行本地化以提高性能和兼容性: | |||
- Roboto | |||
- M PLUS 1p | |||
### 如何更新字体文件 | |||
1. 下载字体文件: | |||
- 访问 https://fonts.google.com/ 搜索并下载需要的字体 | |||
- 或直接使用这些链接: | |||
- Roboto: https://fonts.google.com/download?family=Roboto | |||
- M PLUS 1p: https://fonts.google.com/download?family=M+PLUS+1p | |||
2. 转换为WOFF2格式 | |||
- 使用在线转换工具如 https://transfonter.org/ 或 https://cloudconvert.com/ttf-to-woff2 | |||
- 或使用字体工具如 `fonttools`:`pip install fonttools brotli` 然后运行 `python -m fontTools.ttLib.woff2 compress 字体文件.ttf -o 字体文件.woff2` | |||
3. 放置文件 | |||
- 将转换后的WOFF2文件放入对应的 `public/fonts/[字体名称]` 目录中 | |||
@@ -1,4 +1,53 @@ | |||
@import url('https://fonts.googleapis.com/css2?family=M+PLUS+1p:wght@100;300;400;500;700;800;900&family=Montserrat:ital,wght@0,100..900;1,100..900&family=Noto+Sans+JP:wght@100..900&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap'); | |||
@font-face { | |||
font-family: 'M PLUS 1p'; | |||
font-style: normal; | |||
font-weight: 400; | |||
font-display: swap; | |||
src: url('../fonts/m-plus-1p/MPLUS1p-Regular.woff2') format('woff2'); | |||
} | |||
@font-face { | |||
font-family: 'M PLUS 1p'; | |||
font-style: normal; | |||
font-weight: 500; | |||
font-display: swap; | |||
src: url('../fonts/m-plus-1p/MPLUS1p-Medium.woff2') format('woff2'); | |||
} | |||
@font-face { | |||
font-family: 'M PLUS 1p'; | |||
font-style: normal; | |||
font-weight: 700; | |||
font-display: swap; | |||
src: url('../fonts/m-plus-1p/MPLUS1p-Bold.woff2') format('woff2'); | |||
} | |||
@font-face { | |||
font-family: 'Roboto'; | |||
font-style: normal; | |||
font-weight: 400; | |||
font-display: swap; | |||
src: url('../fonts/roboto/Roboto-Regular.woff2') format('woff2'); | |||
} | |||
@font-face { | |||
font-family: 'Roboto'; | |||
font-style: normal; | |||
font-weight: 500; | |||
font-display: swap; | |||
src: url('../fonts/roboto/Roboto-Medium.woff2') format('woff2'); | |||
} | |||
@font-face { | |||
font-family: 'Roboto'; | |||
font-style: normal; | |||
font-weight: 700; | |||
font-display: swap; | |||
src: url('../fonts/roboto/Roboto-Bold.woff2') format('woff2'); | |||
} | |||
:root { | |||
/* 颜色变量 */ | |||
@@ -17,10 +66,6 @@ | |||
--color-border: #e5e7eb; | |||
} | |||
/* .max-w-screen-2xl{ | |||
background-color: #f59e0b; | |||
} */ | |||
::selection { | |||
background-color: var(--color-accent) !important; | |||
color: var(--color-bg) !important; | |||
@@ -46,11 +91,7 @@ body { | |||
/* 仅在日语环境下应用日文字体 */ | |||
html[lang="ja"] body { | |||
font-family: 'Noto Sans JP', 'M PLUS 1p', sans-serif !important; | |||
} | |||
html[lang="en"] body { | |||
font-family: 'Montserrat', 'Noto Sans JP', sans-serif !important; | |||
font-family: 'M PLUS 1p', sans-serif !important; | |||
} | |||
/* Markdown 内容样式 */ |
@@ -86,7 +86,7 @@ | |||
import { useI18n } from "vue-i18n"; | |||
const { locale, t } = useI18n(); | |||
const config = useRuntimeConfig(); | |||
const defaultLocale = config.public.i18n?.defaultLocale || "en"; | |||
const defaultLocale = config.public.i18n?.defaultLocale || "zh"; | |||
// 获取产品分类数据 | |||
const { data: categoryResponse } = await useAsyncData( |
@@ -361,7 +361,7 @@ import { useSearch } from "~/composables/useSearch"; | |||
*/ | |||
const { t, locale } = useI18n(); | |||
const config = useRuntimeConfig(); | |||
const defaultLocale = config.public.i18n?.defaultLocale || "en"; | |||
const defaultLocale = config.public.i18n?.defaultLocale || "zh"; | |||
const mobileMenuOpen = ref(false); | |||
const isSearchOpen = ref(false); | |||
const searchInputRef = ref<HTMLInputElement | null>(null); |
@@ -1,9 +1,9 @@ | |||
import i18nConfig from "./i18n.config"; | |||
import type { Strategies } from "@nuxtjs/i18n"; | |||
import { resolve } from "path"; | |||
import { readFileSync } from 'fs'; | |||
import { fileURLToPath } from 'url'; | |||
import { dirname, join } from 'path'; | |||
import { readFileSync } from "fs"; | |||
import { fileURLToPath } from "url"; | |||
import { dirname, join } from "path"; | |||
// 尝试导入预生成的路由配置,如果文件不存在则使用默认路由 | |||
let prerenderRoutes = [ | |||
@@ -26,11 +26,11 @@ let prerenderRoutes = [ | |||
try { | |||
const __dirname = dirname(fileURLToPath(import.meta.url)); | |||
const routesPath = join(__dirname, 'prerenderRoutes.json'); | |||
prerenderRoutes = JSON.parse(readFileSync(routesPath, 'utf-8')); | |||
const routesPath = join(__dirname, "prerenderRoutes.json"); | |||
prerenderRoutes = JSON.parse(readFileSync(routesPath, "utf-8")); | |||
console.log(`已加载预渲染路由,共 ${prerenderRoutes.length} 条`); | |||
} catch (err) { | |||
console.warn('未找到预渲染路由配置文件,使用默认路由'); | |||
console.warn("未找到预渲染路由配置文件,使用默认路由"); | |||
} | |||
// https://nuxt.com/docs/api/configuration/nuxt-config | |||
@@ -54,10 +54,10 @@ export default defineNuxtConfig({ | |||
markdown: { | |||
// 配置高亮 | |||
highlight: { | |||
theme: 'github-light' | |||
} | |||
} | |||
} | |||
theme: "github-light", | |||
}, | |||
}, | |||
}, | |||
}, | |||
// i18n 配置 (从外部文件加载) | |||
@@ -90,7 +90,7 @@ export default defineNuxtConfig({ | |||
nitro: { | |||
prerender: { | |||
crawlLinks: false, // 不自动抓取链接 | |||
routes: prerenderRoutes, | |||
routes: [...prerenderRoutes], | |||
ignore: ["/api/**", "/admin/**"], | |||
failOnError: false, // 遇到错误继续生成其他页面 | |||
}, | |||
@@ -114,4 +114,11 @@ export default defineNuxtConfig({ | |||
}, | |||
compatibilityDate: "2025-05-07", | |||
}); | |||
app: { | |||
head: { | |||
charset: "utf-8", | |||
viewport: "width=device-width, initial-scale=1", | |||
}, | |||
}, | |||
}); |
@@ -692,7 +692,7 @@ interface Category { | |||
// 使用i18n | |||
const { t, locale } = useI18n(); | |||
// 默认语言 | |||
const defaultLocale = "ja"; | |||
const defaultLocale = "zh"; | |||
// 获取路由 | |||
const route = useRoute(); | |||
// 断点 |