配置文件
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
import i18next from 'i18next';
import { initReactI18next } from 'react-i18next';
import intervalPlural from 'i18next-intervalplural-postprocessor';
const useSuspense = process.env.JEST_WORKER_ID ? false : true;
const i18n = i18next
.use(Backend)
.use(LanguageDetector)
.use(initReactI18next)
.use(intervalPlural)
.init(
{
// load的namespace
ns: ['common', 'app'],
// 默认会去查找的namespace
// 相同的key值,会优先去app命名空间中查找,若没有,才去common
defaultNS: 'app',
// i18next-xhr-backend 配置项
backend: {
loadPath: '{{ns}}.{{lng}}.json',
addPath: 'locales/add/{{ns}}.{{lng}}',
},
// i18next-browser-languagedetector 配置项
detection: {
order: ['querystring', 'localStorage', 'navigator'],
caches: ['localStorage'],
lookupQuerystring: 'language',
lookupLocalStorage: 'language',
},
// 如果用户选择的语言不被支持,那么使用英文来渲染界面
fallbackLng: ['en-US', 'zh-CN'],
interpolation: {
escapeValue: false, // not needed for react!!
format: function(value, format, lng) {
if (format === 'uppercase') return value.toUpperCase();
if(value instanceof Date) return moment(value).format(format);
return value;
}
},
react: {
wait: true,
useSuspense: useSuspense,
},
whitelist: ['en-US', 'zh-CN'],
saveMissing: true,
},
(error, t) => {
if (!error) {
document.title = t('app.document.title');
}
}
);
i18n.on('languageChanged', (language) => {
console.log(language);
document.title = i18n.t('document.title');
});
i18n.on('missingKey', (lngs, namespace, key, res) => {
console.log(key);
});
export default i18n;
解释
-
intervalPlural插件 用于区间的数量表示; 利用
count
属性可以表示复数,但若要区分某个区间,那么需要使用该插件 具体使用见官方用例即可 -
Backend插件 由于配置项缺乏resources,所以会触发backend请求,从fetch请求里拿到resources文件
分析backend配置项,loadPath是fetch请求的url,addPath何时触发不知道 -
LanguageDetector插件 用于语言检测;可设置检测优先级
-
interpolation
- 设置escapeValue为false是取消转义,因为react本身有该功能
- 设置format格式,展示大写和Date格式
-
languageChanged 语言改变时会触发的事件,可以在这里改变document.title
-
missingKey 当代码中出现资源里没有的key时,会触发该事件;需要注意的是,如果是动态加载页面,只有该页面加载时才会检查
其他
translate使用
import { translate } from 'react-i18next';
// 组件使用
@translate()
class UsageBoard extends Component {
...
}
// 函数式使用
const Usage = props => {
...
}
export default translate()(Usage);
文字中插入组件
有时,一段文案中有些标红、可点击等功能组件
import { withTranslation, Trans } from 'react-i18next';
<Trans
i18nKey="page.help.tips"
components={[<br key="1" />, <br key="2" />]} //注意编码从1开始
/>
国际化json:
"page: {
"help: {
tips: 我是第一行,<0 />我是第二行,<1 />我是第三行
}
}
效果:
我是第一行,
我是第二行,
我是第三行
复数
- i18n自带复数功能,但要注意,其语言(即)为英文时才生效!
中文不生效!
;其他语言不知道
这里的语言一定要是i18n里的language值
,如果只是简单把resources文件里的语言写成英文,也不会生效的
"key": "item",
"key_plural": "items",
i18next.t('key', {count: 0}); // -> "items"
i18next.t('key', {count: 1}); // -> "item"
i18next.t('key', {count: 5}); // -> "items"
i18next.t('key', {count: 00}); // -> 报错
plural前的分割符默认是_
,可通过pluralSeparator
配置修改
- 若想区间复数,那么使用插件intervalPlural,如2-4个item均显示
a few items
{
"key": "{{count}} item",
"key_plural": "{{count}} items",
"key_interval": "(1){one item};(2-7){a few items};(7-inf){a lot of items};",
}
i18next.t('key1_interval', {postProcess: 'interval', count: 1}); // -> "one item"
i18next.t('key1_interval', {postProcess: 'interval', count: 4}); // -> "a few items"
i18next.t('key1_interval', {postProcess: 'interval', count: 100}); // -> "a lot of items"
key值插入
- 若想在翻译中,使用变量,那么使用自带功能即可
{
"nesting1": "1 $t(nesting2)",
"nesting2": "2 $t(nesting3)",
"nesting3": "3",
}
i18next.t('nesting1'); // -> "1 2 3"
- 此方法可与复数功结合使用
{
"time": "$t(hours,{\"count\":{{hours}}}) $t(minutes, {\"count\":{{minutes}}})",
"hours": "{{count}} hour",
"hours_plural": "{{count}} hours",
"minutes": "{{count}} minute",
"minutes_plural": "{{count}} minutes",
}
i18next.t('time', { hours: 3, minutes: 2 }) // -> "3 hours 2 minutes"