Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
3bae5250
Unverified
Commit
3bae5250
authored
Feb 27, 2026
by
Wesley Liddick
Committed by
GitHub
Feb 27, 2026
Browse files
Merge pull request #650 from wucm667/feat/sync-page-title-on-locale-change
feat(i18n): 切换语言时同步更新页面标题
parents
df00805a
82fbf452
Changes
3
Hide whitespace changes
Inline
Side-by-side
frontend/src/i18n/index.ts
View file @
3bae5250
...
...
@@ -68,6 +68,14 @@ export async function setLocale(locale: string): Promise<void> {
i18n
.
global
.
locale
.
value
=
locale
localStorage
.
setItem
(
LOCALE_KEY
,
locale
)
document
.
documentElement
.
setAttribute
(
'
lang
'
,
locale
)
// 同步更新浏览器页签标题,使其跟随语言切换
const
{
resolveDocumentTitle
}
=
await
import
(
'
@/router/title
'
)
const
{
default
:
router
}
=
await
import
(
'
@/router
'
)
const
{
useAppStore
}
=
await
import
(
'
@/stores/app
'
)
const
route
=
router
.
currentRoute
.
value
const
appStore
=
useAppStore
()
document
.
title
=
resolveDocumentTitle
(
route
.
meta
.
title
,
appStore
.
siteName
,
route
.
meta
.
titleKey
as
string
)
}
export
function
getLocale
():
LocaleCode
{
...
...
frontend/src/router/index.ts
View file @
3bae5250
...
...
@@ -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
...
...
frontend/src/router/title.ts
View file @
3bae5250
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
}
`
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment