# react 国际化的常用方法
# 背景:
国际化是企业项目中经常遇到的一个功能,虽然很多成熟的框架都内置了国际化的解决方案,但可能实际开发的过程中出于各种考虑可能不会用太重的框架,这就导致了国际化等功能就需要自己来搭了。
# 调研
首先,肯定是找第三方解决方案,React 国际化框架有多个选择,以下是几个常用的框架及其特点,这些框架都有详细的官方文档和示例,可以根据具体需求选择适合的框架进行 React 国际化的开发。
# react-i18next
官网:https://react.i18next.com/
# 特点:
- 简单易用:提供了简单的 API 和 React 组件,使得国际化变得简单易懂。
- 多种语言支持:支持多种语言,可以轻松地添加和切换不同的语言。
- 动态加载:可以按需加载翻译文件,减少应用程序的初始加载时间。
- 可扩展性:支持插件系统,可以根据需要扩展功能。
- 集成友好:与 React 生态系统中的其他库(如 Redux)和工具(如 Webpack)集成良好。
- 自带切换语言方法
# react-intl
官网:https://formatjs.io/docs/react-intl/
# 特点:
- 全面的国际化支持:提供了丰富的国际化功能,包括日期、时间、数字格式化等。
- 多语言支持:支持多种语言,并且可以根据用户的语言环境自动选择正确的翻译文本。
- 本地化支持:支持本地化内容,如货币符号、时间格式等。
- 翻译管理:提供了工具和 API 来管理翻译文本,包括提取和更新翻译文件。
- 高性能:使用了 React 的虚拟 DOM 和优化技术,提供了高性能的国际化支持。
- 非组件使用困难,不自带切换方法
# react-intl-universal
官网:GitHub - alibaba/react-intl-universal: Internationalize React apps. Not only for Component but also for Vanilla JS.
# 特点:
- 采用了
与组件无关
的方法来实现国际化。国际化的本质其实就是将我们预先设置好的不同语言的句子按照语言环境显示在页面上。不只支持组件中使用,Vanilla JS
也适用。 - 提供了丰富的国际化功能,包括日期、时间、数字格式化等。
- 多语言支持:支持多种语言,并且可以根据用户的语言环境自动选择正确的翻译文本。
- 本地化支持:支持本地化内容,如货币符号、时间格式等。
- 不自带切换方法
# 使用
不同的国际化方案都大同小异,这里仅介绍第三种 react-intl-universal
# i18n
首先来看一下它的技术功能: 国际化
react-intl-universal 采用了 与组件无关
的方法来实现国际化。国际化的本质其实就是将我们预先设置好的不同语言的句子按照语言环境显示在页面上。
import intl from 'react-intl-universal'; |
通过 intl
这个对象来实现初始化和国际化处理。我们可以认为这个 intl是一个单例对象
。我们在 App 启动的时候对其进行初始化,尔后在别的地方再次导入的时候仍然是一个已经初始化过的对象。在这种情况下,国际化处理就会变得异常简单。其次就是准备多语言句子了,传统的在前端处理这个问题是将不同语言的句子放在不同的 json 文件中再导出,文件结构如下:
这样我们就可以在 App 启动或者切换语言的时候导入相应的 json 对象了。
首先是 API 介绍
intl 对象主要有 三个常用的用于国际化处理
的 API, determineLocale、init、get
。
- determineLocale
看到方法名就应该知道它是用来干什么了。它用来确定在整个体系中使用的是哪种语言。
let currentLocale = intl.determineLocale({ urlLocaleKey: "lang", cookieLocaleKey: "lang"}); |
react-intl-universal 确定语言的方式有三种,一个是通过 urlLocaleKey
,即 lang
关键字从 url
中获取是哪种语言。比如:http://localhost?lang=en-US,因为 lang 对应的值是 en_US,所以语言为英文。其次是从 Cookie 获取,因为 Cookie 也是以键值对形式存储的,所以会检查当前域下的 Cookie 是否有对应的 lang
。如果上述两种都没有,那么会默认使用 浏览器当前的语言类型
。当然上述的 urlLocaleKey 和 cookieLocaleKey 是 可以自定义
的,不是固定的 lang
.
- init
init 方法即用来初始化 intl 对象。初始化参数主要是两个,一个是 currentLocale 即当前的语言,另一个是 locales 即当前语言对应的 json 对象,比如 {"en-US":{"key1":"value1"}
或者 {"zh-CN":{"key1":"值1"}}
。
- get
get
方法就相对简单,就是根据键去 intl 中获取对应的值,这里不做过多解释。
前面说了 react-intl-universal 不仅仅可以用来做国际化处理,还可以用来做简单的文本格式化处理。下面我们列举几个常用的。
# Html Snippet
假如我们的 json 文件中有这么一段
... | |
"red": "<p style='color:red'>红色</p>", | |
... |
如果我们直接用 get 方法获取的话,那么会直接把 <p style='color:red'>红色</p>
给打印出来。如果我们想将它以 html 片段的形式打印出来的话,就使用 getHTML
方法,它在获取到句子的时候会进行解析并生成最终的 Html Snippet
。
# Default Message
缺省值其实就是默认值,是对于 json 键值对的默认值。将入我们去获取一个 json 中没有的键值对那么系统就会报错。如何去规避这个问题呢?react-intl-universal 给我们提供了这样一个方法:
intl.get('not-exist-key').defaultMessage('default message') |
这是一个链式调用。如果 json 中没有 not-exist-key
这个键,那就会默认返回 defaultMessage 的参数。简写是 intl.get('not-exist-key').d('default message')
。
# Message With Variables
假如某个句子包含了一个变量怎么办?比如一个用户名,我们只有在用户登录的时候才知道他的用户名。
{ "me": "你好,我是{me}"} |
此时就用到了 get 放的第二个参数。对于上面的例子,我们可以这样处理:
<p>{intl.get('me', {'me': '皮卡丘'})}</p> |
get 方法会找出句子中 被{}包住的变量me
,然后在第二个参数 (json 对象) 找出 me 对应的值皮卡丘并将 {me}
整个用 皮卡丘
替换。另外需要注意的是, json对象只能为一层,不可嵌套
。
# Display Currency
它还可以用来格式化货币。假如有这么一段句子
{ "price": "这件衣服是 {price,number,CNY} 人民币",} |
如果我们想将一个数字以人民币的形式写进去的话可以这么做:
{intl.get('price', {'price': 1000})} |
最终显示结果是: 这件衣服是 ¥1,000 人民币
其实它做了两件事:一个是加符号,另一个是加分隔符。同时 CNY表示人民币,USD表示美元
。