feat(i18n): 切换语言时同步更新页面标题

- resolveDocumentTitle() 新增 titleKey 参数,优先通过 i18n 翻译
- router beforeEach 中将路由 meta.titleKey 传入标题解析函数
- setLocale() 切换语言后同步刷新 document.title
This commit is contained in:
wucm667
2026-02-26 14:04:13 +08:00
parent c75c6b6858
commit 82fbf452a8
3 changed files with 26 additions and 5 deletions

View File

@@ -41,7 +41,8 @@ const routes: RouteRecordRaw[] = [
component: () => import('@/views/auth/LoginView.vue'),
meta: {
requiresAuth: false,
title: 'Login'
title: 'Login',
titleKey: 'common.login'
}
},
{
@@ -50,7 +51,8 @@ const routes: RouteRecordRaw[] = [
component: () => import('@/views/auth/RegisterView.vue'),
meta: {
requiresAuth: false,
title: 'Register'
title: 'Register',
titleKey: 'auth.createAccount'
}
},
{
@@ -86,7 +88,8 @@ const routes: RouteRecordRaw[] = [
component: () => import('@/views/auth/ForgotPasswordView.vue'),
meta: {
requiresAuth: false,
title: 'Forgot Password'
title: 'Forgot Password',
titleKey: 'auth.forgotPasswordTitle'
}
},
{
@@ -390,7 +393,7 @@ router.beforeEach((to, _from, next) => {
// Set page title
const appStore = useAppStore()
document.title = resolveDocumentTitle(to.meta.title, appStore.siteName)
document.title = resolveDocumentTitle(to.meta.title, appStore.siteName, to.meta.titleKey as string)
// Check if route requires authentication
const requiresAuth = to.meta.requiresAuth !== false // Default to true

View File

@@ -1,9 +1,19 @@
import { i18n } from '@/i18n'
/**
* 统一生成页面标题,避免多处写入 document.title 产生覆盖冲突。
* 优先使用 titleKey 通过 i18n 翻译fallback 到静态 routeTitle。
*/
export function resolveDocumentTitle(routeTitle: unknown, siteName?: string): string {
export function resolveDocumentTitle(routeTitle: unknown, siteName?: string, titleKey?: string): string {
const normalizedSiteName = typeof siteName === 'string' && siteName.trim() ? siteName.trim() : 'Sub2API'
if (typeof titleKey === 'string' && titleKey.trim()) {
const translated = i18n.global.t(titleKey)
if (translated && translated !== titleKey) {
return `${translated} - ${normalizedSiteName}`
}
}
if (typeof routeTitle === 'string' && routeTitle.trim()) {
return `${routeTitle.trim()} - ${normalizedSiteName}`
}