国际化的原理和使用
1. 国际化初始化
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import { localStg } from '@/utils/storage';
import locales from './locale';
export const reactI18nextInstance = i18n.use(initReactI18next);
/** Setup plugin i18n */
export async function setupI18n() {
await reactI18nextInstance.init({
interpolation: {
escapeValue: false
},
lng: localStg.get('lang') || 'zh-CN',
resources: locales
});
}
export const $t = reactI18nextInstance.t;
export function setLng(locale: App.I18n.LangType) {
reactI18nextInstance.changeLanguage(locale);
}
- 引入
i18next
并结合react-i18next
进行整合。 resources
中包含各个语言的映射文件(如zh-CN
,en-US
等)。lng
决定当前使用的语言,会从本地存储中读取或默认设为'zh-CN'
。
2. 语言文件资源
// locale/index.ts
import enUS from './langs/en-us';
import zhCN from './langs/zh-cn';
const locales: Record<App.I18n.LangType, App.I18n.Schema> = {
'en-US': {
translation: enUS
},
'zh-CN': {
translation: zhCN
}
};
export default locales;
- 这里将所有支持的语言打包在
locales
对象中,供 i18n 初始化时使用。 - 每个语言下都有一个
translation
子对象,用来存放文本映射。
3. 在组件中使用翻译
- 可以使用
import { useTranslation } from 'react-i18next';
获取t
函数进行翻译。 - 或使用上述
export const $t = reactI18nextInstance.t;
直接在工具函数里访问。
示例:
import React from 'react';
import { useTranslation } from 'react-i18next';
function Example() {
const { t } = useTranslation();
return <div>{t('common.ok')}</div>;
}
- 若写在业务逻辑中,可直接使用
$t('common.ok')
。
动态路由与国际化
在路由配置中,如果给定了 i18nKey
,框架会优先使用国际化键值进行翻译;如果未指定 i18nKey
,则直接使用 title
作为静态文本。例如:
/**
* 路由标题
*
* 可用于文档标题中
*/
title: string;
/**
* 路由的国际化键值
*
* 如果设置,将用于 i18n,此时 title 将被忽略
*/
i18nKey?: App.I18n.I18nKey;
- 如果存在
i18nKey
,系统会调用$t(i18nKey)
来获取路由标题。 - 如果 不想 用国际化,就不要指定
i18nKey
,只给title
即可。例如:{ path: '/demo', name: 'demo', title: '示例页面' // i18nKey: 'route.demo' <-- 不要加这行 }
取消自动生成 i18nKey
在本框架中,通过 build/plugins/router.ts
中的 onRouteMetaGen
Hook,你可以看到:
// build/plugins/router.ts
export function setupElegantRouter() {
return ElegantReactRouter({
customRoutes: {
names: [
// ...
]
},
onRouteMetaGen(routeName) {
const key = routeName as RouteKey;
const constantRoutes: RouteKey[] = ['403', '404', '500'];
// 这里会自动生成 i18nKey
const meta: Partial<RouteMeta> = {
i18nKey: `route.${key}` as App.I18n.I18nKey,
title: key
};
if (constantRoutes.includes(key)) {
meta.constant = true;
}
return meta;
}
});
}
- 如果你想取消国际化,让路由只使用 title 而不自动生成 i18nKey,只需在这里删除或注释掉这行:
i18nKey: `route.${key}` as App.I18n.I18nKey,
- 随后,路由元信息
meta
中就不会再带i18nKey
字段,从而不会自动调用$t(...)
翻译。
如何彻底禁用国际化
1. 不再调用 setupI18n
如果你想让整个应用完全不走国际化逻辑,可以直接移除或注释掉 main.tsx
或 main.jsx
中的 setupI18n()
调用。
示例:
function setupApp() {
- setupI18n(); // 注释或删掉
const container = document.getElementById('root');
// ...
}
2. 不再导入 i18n 的任何文件
- 移除/删除所有
import { useTranslation } from 'react-i18next'
或$t(...)
的使用。 - 若有语法报错,可以在本地删除
locale
文件夹或不再将其打包。
3. 去掉 i18nKey
相关配置
- 在路由元信息或加载路由的地方,不再传入
i18nKey
。 - 在自动生成配置中(
onRouteMetaGen
),移除对i18nKey
的生成逻辑。
这样,就彻底避免了国际化依赖,整个应用将使用纯文本或其它自定义逻辑显示标题与内容。
注意
如果当前项目原先已经包含了国际化逻辑,但目前暂时不需要它,那么保留现有的 i18n 配置并不再主动使用即可。一般来说,这样不会对你现有的功能造成实质影响。以下是一些可选的“最小变动”方式:
-
保留 setupI18n 不删除
setupI18n()
调用,也不删除locales
文件夹等。这些代码留在项目里不会影响正常构建或运行。- 只是不再使用
$t()
或useTranslation()
等函数翻译页面文本即可。
- 只是不再使用
-
不再生成或填写
i18nKey
- 在路由元信息(或自动生成配置)中,去掉
i18nKey
相关逻辑或留空; - 这样路由标题会自动回退到
title
字段,不会再经过国际化翻译。
- 在路由元信息(或自动生成配置)中,去掉
-
后续需要国际化时再启用
- 如果今后想重新启用多语言,只需再次在页面中调用
$t()
或使用i18nKey
,原先的配置依旧可用,省去了重复搭建的成本。
- 如果今后想重新启用多语言,只需再次在页面中调用
简单来说,你可以不动已有的 i18n 代码,只要路由或页面不再使用 i18nKey
并不主动调用翻译函数,就相当于“暂时禁用”了国际化功能,也不会对项目带来额外的负担。后续如果需要多语言支持,随时可以在此基础上继续开发。
小结
- 框架默认支持多语言:通过
i18next + react-i18next
在全局初始化,并在路由元信息中通过i18nKey
与title
配合使用。 - 灵活控制是否启用国际化:
- 如果路由的
i18nKey
存在,则优先翻译;若只想用标题文本,就不要设置i18nKey
。 - 若想完全关闭国际化,可移除
setupI18n()
、所有翻译相关调用,以及路由中自动生成i18nKey
的逻辑。
- 如果路由的
- 定制化路由标题:可以在
onRouteMetaGen
或手动配置中自定义字段,例如只返回title
而不返回i18nKey
,从而实现只使用静态文本的路由标题。
通过这种方式,你可以在需要多语言时轻松启用国际化,在不需要多语言时则可以简化掉相关逻辑,让应用代码更干净、打包体积更小。
Last updated on