@umijs/plugin-locale
国际化插件,用于解决 i18n 问题。
启用方式
配置 locale
开启。
介绍
包含以下功能,
约定式多语言支持
比如以下目录,项目就拥有了 zh-CN
与 en-US
国际化语言切换:
+ src
+ locales
- zh-CN.ts
- en-US.ts
+ pages
多语言文件的命名规范:<lang><分割符(通过 baseSeparator 配置)><COUNTRY>.js
多语言文件的内容规范:键-值组成的字面量,如下:
// src/locales/zh-CN.js
export default {
WELCOME_TO_UMI_WORLD: '{name},欢迎光临umi的世界',
};
// src/locales/en-US.js
export default {
WELCOME_TO_UMI_WORLD: "{name}, welcome to umi's world",
};
如果项目配置了
singular: true
,locales
要改成locale
import from umi
@umijs/plugin-locale 基于 react-intl 封装,支持其所有的 api,详情可以看 这里。为了方便使用我们也添加了一些其他的功能,这里将会列举所有的 api,并且展示它的功能。
addLocale
动态的增加语言,增加语言之后可以通过 getAllLocales 获得列表。addLocale 三个参数。
name
语言的 key。例如 zh-TWmessage
语言的 id 列表。 例如:{ // id 列表 name: ‘妳好,{name}’, }- 相应的
momentLocale
和antd
配置
import zhTW from 'antd/es/locale/zh_TW';
// 动态增加新语言
addLocale(
'zh-TW',
{
// id 列表
name: '妳好,{name}',
},
{
momentLocale: 'zh-tw',
antd: zhTW,
},
);
getAllLocales
获取当前获得所有国际化文件的列表,默认会在 locales
文件夹下寻找类似 en-US.(js|json|ts)
文件。
import { getAllLocales } from 'umi';
console.log(getAllLocales()); // [en-US,zh-CN,...]
getLocale
getLocale
将获得当前选择的语言。
import { getLocale } from 'umi';
console.log(getLocale()); // en-US | zh-CN
useIntl
useIntl
是最常用的 api,它可以获得 formatMessage
等 api 来进行具体的值绑定。
// en-US.json
export default {
name: 'Hi, {name}',
};
//page/index.tsx
import React, { useState } from 'react';
import { useIntl } from 'umi';
export default function() {
const intl = useIntl();
return (
<button type="primary">
{intl.formatMessage(
{
id: 'name',
defaultMessage: '你好,旅行者',
},
{
name: '旅行者',
},
)}
</button>
);
}
setLocale
设置切换语言,默认会刷新页面,可以通过设置第二个参数为 false
,来实现无刷新动态切换。
import { setLocale } from 'umi';
// 刷新页面
setLocale('zh-TW', true);
// 不刷新页面
setLocale('zh-TW', false);
配置
- Type:
object
目录约定:
构建时配置
开启 locale: {}
后,默认是如下配置:
export default {
locale: {
default: 'zh-CN',
antd: false,
title: false,
baseNavigator: true,
baseSeparator: '-',
}
}
baseSeparator
- Type:
string
- Default:
-
国家(lang) 与 语言(language) 之间的分割符。
默认情况下为 -
,返回的语言及目录文件为 zh-CN
、en-US
、sk
等。
default
- Type:
string
- Default:
zh-CN
默认语言,当检测不到具体语言时,展示 default
中指定的语言。
若
baseNavigator
指定为_
,default
默认为zh_CN
。
antd
- Type:
boolean
- Default: false
开启后,支持 antd 国际化。
title
- Type:
boolean
- Default: false
标题国际化。
在项目中配置的 title
及路由中的 title
可直接使用国际化 key,自动被转成对应语言的文案,例如:
locales
目录下有:
// src/locales/zh-CN.js
export default {
'site.title': '站点 - 标题',
'about.title': '关于 - 标题',
}
// src/locales/en-US.js
export default {
'site.title': 'English Title',
'about.title': 'About - Title',
}
项目配置如下:
// .umirc.js
export default {
title: 'site.title',
routes: [
{
path: '/',
component: 'Index',
},
{
path: '/about',
component: 'About',
title: 'about.title',
}
]
}
访问页面时:
/
路由,标题在中文时为站点 - 标题
,英文时为English Title
/about
路由,标题在中文时为关于 - 标题
,英文时为About Title
baseNavigator
- Type:
boolean
- Default: true
开启浏览器语言检测。
默认情况下,当前语言环境的识别按照:localStorage
中 umi_locale
值 > 浏览器检测 > default 设置的默认语言 > 中文
运行时配置
支持运行时对国际化做一些扩展与定制,例如自定义语言识别等。
getLocale
自定义语言获取逻辑,比如识别链接 ?locale=${lang}
当做当前页面的语言。
// src/app.js
import qs from 'qs';
export const locale = {
getLocale() {
const { search } = window.location;
const { locale = 'zh-CN' } = qs.parse(search, { ignoreQueryPrefix: true });
return locale;
},
}
setLocale
自定义语言切换逻辑。其中有三个参数:
- lang: 需要切换的语言
- realReload: 是否需要刷新页面,这个是由页面调用
setLocale(lang, true)
透传。 - updater:是否需要强制更新当前组件国际化状态。
比如根据要切换的语言,跳转到相应 url:
// src/app.js
export const locale = {
setLocale({ lang, realReload, updater }) {
history.push(`/?locale=${lang}`);
updater();
}
}
FAQ
为什么不要直接使用 formatMessage 这个语法糖?
虽然 formatMessage 使用起来会非常方便,但是它脱离了 react 的生命周期,最严重的问题就是切换语言时无法触发 dom 重新渲染。为了解决这个问题,我们切换语言时会刷新一下浏览器,用户体验很差,所以推荐大家使用 useIntl
或者 injectIntl
,可以实现同样的功能。