diff --git a/auto-imports.d.ts b/auto-imports.d.ts index 3f8d1fa..beab76e 100644 --- a/auto-imports.d.ts +++ b/auto-imports.d.ts @@ -111,6 +111,7 @@ declare global { const resolveComponent: typeof import('vue')['resolveComponent'] const resolveRef: typeof import('@vueuse/core')['resolveRef'] const resolveUnref: typeof import('@vueuse/core')['resolveUnref'] + const routeI18nInstance: typeof import('./src/locales-utils/i18n-auto-imports')['routeI18nInstance'] const setActivePinia: typeof import('pinia')['setActivePinia'] const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix'] const setViewportCSSVars: typeof import('utils4u/browser')['setViewportCSSVars'] @@ -455,6 +456,7 @@ declare module 'vue' { readonly resolveComponent: UnwrapRef readonly resolveRef: UnwrapRef readonly resolveUnref: UnwrapRef + readonly routeI18nInstance: UnwrapRef readonly setActivePinia: UnwrapRef readonly setMapStoreSuffix: UnwrapRef readonly setViewportCSSVars: UnwrapRef diff --git a/src/composables/useMetaLayoutsMenuOptions.tsx b/src/composables/useMetaLayoutsMenuOptions.tsx index faf772e..922ef44 100644 --- a/src/composables/useMetaLayoutsMenuOptions.tsx +++ b/src/composables/useMetaLayoutsMenuOptions.tsx @@ -8,27 +8,7 @@ import IconMenuRounded from '~icons/material-symbols/menu-rounded'; export function useMetaLayoutsNMenuOptions({ menuInstRef }: { menuInstRef: Ref }) { const router = useRouter(); - const { t, te, locale } = useI18n({ - inheritLocale: true, - useScope: 'local', - missing: (locale, key) => { - consola.warn(`菜单翻译缺失: locale=${locale}, key=${key}`); - return key; - }, - fallbackRoot: true, - messages: i18nRouteMessages, - }); - - // FIXME: 这个逻辑放在这里不太合适。 - watch( - () => [router.currentRoute.value, locale.value] as const, - ([currentRoute]) => { - const routeName = currentRoute.name; - const text = te(routeName) ? t(routeName) : routeName; - currentRoute.meta!.title = text; - }, - { immediate: true }, - ); + const { t, te } = routeI18nInstance.global; // 获取路由表但是不包含布局路由 const routes = createGetRoutes(router)(); diff --git a/src/locales-utils/i18n-auto-imports.ts b/src/locales-utils/i18n-auto-imports.ts index 8848025..072fc09 100644 --- a/src/locales-utils/i18n-auto-imports.ts +++ b/src/locales-utils/i18n-auto-imports.ts @@ -2,7 +2,9 @@ * All i18n resources specified in the plugin `include` option can be loaded * at once using the import syntax */ +import { router } from '@/plugins/00.router-plugin'; import messages from '@intlify/unplugin-vue-i18n/messages'; +import { createGetRoutes } from 'virtual:meta-layouts'; import { createI18n } from 'vue-i18n'; @@ -26,6 +28,44 @@ export const i18nInstance = createI18n({ messages, }); -watchEffect(() => { - locale.value = i18nInstance.global.locale.value; +export const routeI18nInstance = createI18n({ + legacy: false, // you must set `false`, to use Composition API + locale: locale.value, + inheritLocale: true, + useScope: 'local', + missing: (locale, key) => { + consola.warn(`菜单翻译缺失: locale=${locale}, key=${key}`); + return key; + }, + fallbackRoot: true, + messages: i18nRouteMessages, }); + +watchEffect( + () => { + locale.value = i18nInstance.global.locale.value; + }, + { flush: 'sync' }, +); + +watch( + () => i18nInstance.global.locale.value, + () => { + routeI18nInstance.global.locale.value = i18nInstance.global.locale.value; + + const routes = createGetRoutes(router)(); // 获取路由表但是不包含布局路由 + + routes.forEach((route) => { + const { t, te } = routeI18nInstance.global; + + if (router.currentRoute.value.name) { + router.currentRoute.value.meta.title = t(router.currentRoute.value.name as string); + } + + route.meta = route.meta || {}; + const routeName = route.name as string; + route.meta.title = te(routeName) ? t(routeName) : routeName; + }); + }, + { immediate: true, flush: 'sync' }, +); diff --git a/src/locales-utils/route-messages/route-messages-auto-imports.ts b/src/locales-utils/route-messages/route-messages-auto-imports.ts index ef0e782..8c1b3e8 100644 --- a/src/locales-utils/route-messages/route-messages-auto-imports.ts +++ b/src/locales-utils/route-messages/route-messages-auto-imports.ts @@ -1,7 +1,7 @@ import type { I18nOptions } from 'vue-i18n'; const modules = import.meta.glob(['./*.ts', '!./route-messages-auto-imports'], { - eager: true, + eager: true /* true 为同步,false 为异步 */, import: 'default', }); diff --git a/src/pages/demos/i18n-demo.page.vue b/src/pages/demos/i18n-demo.page.vue index 628e5c7..e079586 100644 --- a/src/pages/demos/i18n-demo.page.vue +++ b/src/pages/demos/i18n-demo.page.vue @@ -21,6 +21,8 @@ function setLocale(newLocale: 'en-US' | 'zh-CN') { {{ t('page.i18n-demo.hello', { name: 'Kilo' }) }} + $route.meta: {{ $route.meta }} + English 简体中文 diff --git a/src/plugins/00.router-plugin.types.ts b/src/plugins/00.router-plugin.types.ts index 0658753..859429f 100644 --- a/src/plugins/00.router-plugin.types.ts +++ b/src/plugins/00.router-plugin.types.ts @@ -13,7 +13,7 @@ declare module 'vue-router' { hideInMenu?: boolean; /** - * @description 菜单标题 //!⚠️通过多语言标题方案(搜`PageTitleLocalizations`)维护标题 + * @description 菜单标题 // !⚠️通过多语言标题方案(搜`PageTitleLocalizations`)维护标题 */ title?: string;