@umijs/plugin-locale

国际化插件,用于解决 i18n 问题。

启用方式

配置 locale 开启。

介绍

包含以下功能,

约定式多语言支持

比如以下目录,项目就拥有了 zh-CNen-US 国际化语言切换:

  1. + src
  2. + locales
  3. - zh-CN.ts
  4. - en-US.ts
  5. + pages

多语言文件的命名规范:<lang><分割符(通过 baseSeparator 配置)><COUNTRY>.js

多语言文件的内容规范:键-值组成的字面量,如下:

  1. // src/locales/zh-CN.js
  2. export default {
  3. WELCOME_TO_UMI_WORLD: '{name},欢迎光临umi的世界',
  4. };
  1. // src/locales/en-US.js
  2. export default {
  3. WELCOME_TO_UMI_WORLD: "{name}, welcome to umi's world",
  4. };

如果项目配置了 singular: truelocales 要改成 locale

import from umi

@umijs/plugin-locale 基于 react-intl 封装,支持其所有的 api,详情可以看 这里。为了方便使用我们也添加了一些其他的功能,这里将会列举所有的 api,并且展示它的功能。

addLocale

动态的增加语言,增加语言之后可以通过 getAllLocales 获得列表。addLocale 三个参数。

  • name 语言的 key。例如 zh-TW
  • message 语言的 id 列表。 例如:{ // id 列表 name: ‘妳好,{name}’, }
  • 相应的 momentLocaleantd 配置
  1. import zhTW from 'antd/es/locale/zh_TW';
  2. // 动态增加新语言
  3. addLocale(
  4. 'zh-TW',
  5. {
  6. // id 列表
  7. name: '妳好,{name}',
  8. },
  9. {
  10. momentLocale: 'zh-tw',
  11. antd: zhTW,
  12. },
  13. );

getAllLocales

获取当前获得所有国际化文件的列表,默认会在 locales 文件夹下寻找类似 en-US.(js|json|ts) 文件。

  1. import { getAllLocales } from 'umi';
  2. console.log(getAllLocales()); // [en-US,zh-CN,...]

getLocale

getLocale 将获得当前选择的语言。

  1. import { getLocale } from 'umi';
  2. console.log(getLocale()); // en-US | zh-CN

useIntl

useIntl 是最常用的 api,它可以获得 formatMessage 等 api 来进行具体的值绑定。

  1. // en-US.json
  2. export default {
  3. name: 'Hi, {name}',
  4. };
  1. //page/index.tsx
  2. import React, { useState } from 'react';
  3. import { useIntl } from 'umi';
  4. export default function() {
  5. const intl = useIntl();
  6. return (
  7. <button type="primary">
  8. {intl.formatMessage(
  9. {
  10. id: 'name',
  11. defaultMessage: '你好,旅行者',
  12. },
  13. {
  14. name: '旅行者',
  15. },
  16. )}
  17. </button>
  18. );
  19. }

setLocale

设置切换语言,默认会刷新页面,可以通过设置第二个参数为 false ,来实现无刷新动态切换。

  1. import { setLocale } from 'umi';
  2. // 刷新页面
  3. setLocale('zh-TW', true);
  4. // 不刷新页面
  5. setLocale('zh-TW', false);

@umijs-plugin-locale - 图1

配置

  • Type: object

目录约定:

构建时配置

开启 locale: {} 后,默认是如下配置:

  1. export default {
  2. locale: {
  3. default: 'zh-CN',
  4. antd: false,
  5. title: false,
  6. baseNavigator: true,
  7. baseSeparator: '-',
  8. }
  9. }

baseSeparator

  • Type: string
  • Default: -

国家(lang) 与 语言(language) 之间的分割符。

默认情况下为 -,返回的语言及目录文件为 zh-CNen-USsk 等。

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 目录下有:

  1. // src/locales/zh-CN.js
  2. export default {
  3. 'site.title': '站点 - 标题',
  4. 'about.title': '关于 - 标题',
  5. }
  6. // src/locales/en-US.js
  7. export default {
  8. 'site.title': 'English Title',
  9. 'about.title': 'About - Title',
  10. }

项目配置如下:

  1. // .umirc.js
  2. export default {
  3. title: 'site.title',
  4. routes: [
  5. {
  6. path: '/',
  7. component: 'Index',
  8. },
  9. {
  10. path: '/about',
  11. component: 'About',
  12. title: 'about.title',
  13. }
  14. ]
  15. }

访问页面时:

  • / 路由,标题在中文时为 站点 - 标题,英文时为 English Title
  • /about 路由,标题在中文时为 关于 - 标题,英文时为 About Title

baseNavigator

  • Type: boolean
  • Default: true

开启浏览器语言检测。

默认情况下,当前语言环境的识别按照:localStorageumi_locale 值 > 浏览器检测 > default 设置的默认语言 > 中文

运行时配置

支持运行时对国际化做一些扩展与定制,例如自定义语言识别等。

getLocale

自定义语言获取逻辑,比如识别链接 ?locale=${lang} 当做当前页面的语言。

  1. // src/app.js
  2. import qs from 'qs';
  3. export const locale = {
  4. getLocale() {
  5. const { search } = window.location;
  6. const { locale = 'zh-CN' } = qs.parse(search, { ignoreQueryPrefix: true });
  7. return locale;
  8. },
  9. }

setLocale

自定义语言切换逻辑。其中有三个参数:

  • lang: 需要切换的语言
  • realReload: 是否需要刷新页面,这个是由页面调用 setLocale(lang, true) 透传。
  • updater:是否需要强制更新当前组件国际化状态。

比如根据要切换的语言,跳转到相应 url:

  1. // src/app.js
  2. export const locale = {
  3. setLocale({ lang, realReload, updater }) {
  4. history.push(`/?locale=${lang}`);
  5. updater();
  6. }
  7. }

FAQ

为什么不要直接使用 formatMessage 这个语法糖?

虽然 formatMessage 使用起来会非常方便,但是它脱离了 react 的生命周期,最严重的问题就是切换语言时无法触发 dom 重新渲染。为了解决这个问题,我们切换语言时会刷新一下浏览器,用户体验很差,所以推荐大家使用 useIntl 或者 injectIntl,可以实现同样的功能。