本次提交主要进行了以下修改: 1. 在nuxt.config.ts中调整了预渲染路由的配置方式,使用扩展运算符以提高可读性。 2. 在README.md中新增了字体本地化指南,详细说明了如何更新和使用本地字体。 3. 在styles.css中移除了Google字体的直接引用,改为使用本地化的字体文件,提升性能。 4. 新增了多个字体文件(M PLUS 1p和Roboto)的本地化支持。 5. 在多个组件中将默认语言设置为中文,以符合项目需求。 这些改动旨在提升代码的可维护性和性能,同时增强用户体验。master
``` | ``` | ||||
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. | 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/[字体名称]` 目录中 | |||||
@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 { | :root { | ||||
/* 颜色变量 */ | /* 颜色变量 */ | ||||
--color-border: #e5e7eb; | --color-border: #e5e7eb; | ||||
} | } | ||||
/* .max-w-screen-2xl{ | |||||
background-color: #f59e0b; | |||||
} */ | |||||
::selection { | ::selection { | ||||
background-color: var(--color-accent) !important; | background-color: var(--color-accent) !important; | ||||
color: var(--color-bg) !important; | color: var(--color-bg) !important; | ||||
/* 仅在日语环境下应用日文字体 */ | /* 仅在日语环境下应用日文字体 */ | ||||
html[lang="ja"] 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 内容样式 */ | /* Markdown 内容样式 */ |
import { useI18n } from "vue-i18n"; | import { useI18n } from "vue-i18n"; | ||||
const { locale, t } = useI18n(); | const { locale, t } = useI18n(); | ||||
const config = useRuntimeConfig(); | const config = useRuntimeConfig(); | ||||
const defaultLocale = config.public.i18n?.defaultLocale || "en"; | |||||
const defaultLocale = config.public.i18n?.defaultLocale || "zh"; | |||||
// 获取产品分类数据 | // 获取产品分类数据 | ||||
const { data: categoryResponse } = await useAsyncData( | const { data: categoryResponse } = await useAsyncData( |
*/ | */ | ||||
const { t, locale } = useI18n(); | const { t, locale } = useI18n(); | ||||
const config = useRuntimeConfig(); | const config = useRuntimeConfig(); | ||||
const defaultLocale = config.public.i18n?.defaultLocale || "en"; | |||||
const defaultLocale = config.public.i18n?.defaultLocale || "zh"; | |||||
const mobileMenuOpen = ref(false); | const mobileMenuOpen = ref(false); | ||||
const isSearchOpen = ref(false); | const isSearchOpen = ref(false); | ||||
const searchInputRef = ref<HTMLInputElement | null>(null); | const searchInputRef = ref<HTMLInputElement | null>(null); |
import i18nConfig from "./i18n.config"; | import i18nConfig from "./i18n.config"; | ||||
import type { Strategies } from "@nuxtjs/i18n"; | import type { Strategies } from "@nuxtjs/i18n"; | ||||
import { resolve } from "path"; | 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 = [ | let prerenderRoutes = [ | ||||
try { | try { | ||||
const __dirname = dirname(fileURLToPath(import.meta.url)); | 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} 条`); | console.log(`已加载预渲染路由,共 ${prerenderRoutes.length} 条`); | ||||
} catch (err) { | } catch (err) { | ||||
console.warn('未找到预渲染路由配置文件,使用默认路由'); | |||||
console.warn("未找到预渲染路由配置文件,使用默认路由"); | |||||
} | } | ||||
// https://nuxt.com/docs/api/configuration/nuxt-config | // https://nuxt.com/docs/api/configuration/nuxt-config | ||||
markdown: { | markdown: { | ||||
// 配置高亮 | // 配置高亮 | ||||
highlight: { | highlight: { | ||||
theme: 'github-light' | |||||
} | |||||
} | |||||
} | |||||
theme: "github-light", | |||||
}, | |||||
}, | |||||
}, | |||||
}, | }, | ||||
// i18n 配置 (从外部文件加载) | // i18n 配置 (从外部文件加载) | ||||
nitro: { | nitro: { | ||||
prerender: { | prerender: { | ||||
crawlLinks: false, // 不自动抓取链接 | crawlLinks: false, // 不自动抓取链接 | ||||
routes: prerenderRoutes, | |||||
routes: [...prerenderRoutes], | |||||
ignore: ["/api/**", "/admin/**"], | ignore: ["/api/**", "/admin/**"], | ||||
failOnError: false, // 遇到错误继续生成其他页面 | failOnError: false, // 遇到错误继续生成其他页面 | ||||
}, | }, | ||||
}, | }, | ||||
compatibilityDate: "2025-05-07", | compatibilityDate: "2025-05-07", | ||||
}); | |||||
app: { | |||||
head: { | |||||
charset: "utf-8", | |||||
viewport: "width=device-width, initial-scale=1", | |||||
}, | |||||
}, | |||||
}); |
// 使用i18n | // 使用i18n | ||||
const { t, locale } = useI18n(); | const { t, locale } = useI18n(); | ||||
// 默认语言 | // 默认语言 | ||||
const defaultLocale = "ja"; | |||||
const defaultLocale = "zh"; | |||||
// 获取路由 | // 获取路由 | ||||
const route = useRoute(); | const route = useRoute(); | ||||
// 断点 | // 断点 |