react项目国际化 react-intl-universal 中文 api 使用方法

方英耀
2023-12-01

react-intl-universal是由阿里巴巴集团开发的React国际化软件包。

特征

  • 不仅可以在React.Component中使用,还可以在Vanilla JS中使用。
  • 简单。只有三个主要的API和一个可选的帮助器。
  • 显示不同语言环境的数字,货币,日期和时间。
  • 多元化字符串中的标签。
  • 消息中的支持变量。
  • 在消息中支持HTML。
  • 支持150多种语言。
  • 在浏览器和Node.js中运行。
  • 消息格式由ICU标准严格执行。
  • 支持嵌套JSON格式的语言环境数据。

安装

npm install react-intl-universal --save

基本使用

我们将需要国际化的东西以键值对的形式分别写入不同的配置文件中。然后再入口文件处进行intl的初始化。

import React from 'react';
import ReactDOM from 'react-dom';
import intl from 'react-intl-universal';
import App from './App';

const locales = {
    'en': require('../../locales/en_US.json'),
    'zh': require('../../locales/zh_CN.json'),
};
let lang = (navigator.languages && navigator.languages[0]) || navigator.language
intl.init({
  currentLocale: lang.split('-')[0],
  locales: locales
})
ReactDOM.render(<App />,document.getElementById('root'));

zh_CN.json

{
  "Userpanel":"用户面板"
  }

en_US.json

{
  "Userpanel":"User panel"
  }

之后就可以在需要国际化的组件中使用intl的API进行国际化了。

例如

 <NavLink  activeClassName="activeNavLink" to={"/back/panel/list"}>
        <i className="iconfont anticon">&#xe628;</i>
        <span>{intl.get('Userpanel')}</span>
  </NavLink>

基本范例

在以下示例中,我们intl使用应用语言环境数据(locales)进行初始化,并确定动态使用哪个语言环境(currentLocale)。然后使用intl.get(…)获取国际化消息。就这样。很简单!

请注意,您不必加载所有语言环境数据,只需按需加载当前语言环境数据。请参考示例以获取更多详细信息。

import intl from 'react-intl-universal';
// common locale data
require('intl/locale-data/jsonp/en.js');
require('intl/locale-data/jsonp/zh.js');

// app locale data
const locales = {
  "en-US": require('./locales/en-US.js'),
  "zh-CN": require('./locales/zh-CN.js'),
};

class App extends Component {

  state = {initDone: false}

  componentDidMount() {
    this.loadLocales();
  }

  loadLocales() {
    // init method will load CLDR locale data according to currentLocale
    // react-intl-universal is singleton, so you should init it only once in your app
    intl.init({
      currentLocale: 'en-US', // TODO: determine locale here
      locales,
    })
    .then(() => {
      // After loading CLDR locale data, start to render
	  this.setState({initDone: true});
    });
  }

  render() {
    return (
      this.state.initDone &&
      <div>
        {intl.get('SIMPLE')}
      </div>
    );
  }

}

带变量的消息

如果消息包含变量,则将{variable_name}其直接替换为字符串。在下面的示例中,有两个变量{name}{where},代表get方法中变量的第二个参数被替换为字符串。

语言环境数据:

{ "HELLO": "Hello, {name}. Welcome to {where}!" }

JS代码:

intl.get('HELLO', { name: 'Tony', where: 'Alibaba' }) // "Hello, Tony. Welcome to Alibaba!"

复数形式和数以千计的分隔符

语言环境数据:

{ "PHOTO": "You have {num, plural, =0 {no photos.} =1 {one photo.} other {# photos.}}" }

JS代码:

intl.get('PHOTO', { num: 0 }); // "You have no photos."
intl.get('PHOTO', { num: 1 }); // "You have one photo."
intl.get('PHOTO', { num: 1000000 }); // "You have 1,000,000 photos."

复数标签支持标准的ICU消息语法。

千位分隔符的数量也根据用户的区域设置而变化。根据该 文件,美国使用句点来表示小数位。许多其他国家/地区使用逗号代替。

显示货币
语言环境数据:

{ "SALE_PRICE": "The price is {price, number, USD}" }

JS代码:

intl.get('SALE_PRICE', { price: 123456.78 }); // The price is $123,456.78

如前所述,语言环境数据采用ICU消息格式。

语法为{名称,类型,格式}。这是说明:

  • name是消息中的变量名称。在这种情况下为price
  • 类型是值如式numberdate,和time
  • format是可选的,并且是该值的显示格式的附加信息。在这种情况下为USD
  • 如果typenumberformat省略,则结果为带数千个分隔符的格式化数字。如果format是货币代码之一,它将以相应的货币格式显示。

显示日期

语言环境数据:

{
  "SALE_START": "Sale begins {start, date}",
  "SALE_END": "Sale ends {end, date, long}"
}

JS代码:

intl.get('SALE_START', {start:new Date()}); // Sale begins 4/19/2017
intl.get('SALE_END', {end:new Date()}); // Sale ends April 19, 2017

如果typedate,则format具有以下值:

  • short 显示日期尽可能短
  • medium 显示该月的简短文字说明
  • long 显示该月的长文字表示
  • full 显示最详细的日期

显示时间

语言环境数据:

{
  "COUPON": "Coupon expires at {expires, time, medium}"
}

JS代码:

intl.get('COUPON', {expires:new Date()}); // Coupon expires at 6:45:44 PM

如果typetime,则format具有以下值:

  • short 以小时和分钟显示时间
  • medium 以小时,分钟和秒显示时间
  • long 显示带有小时,分钟,秒和时区的时间

预设讯息

当当前区域设置中不存在特定键时,您可能希望使其返回默认消息。使用defaultMessage后的方法get方法。例如,

语言环境数据:

{ "HELLO": "Hello, {name}" }

JS代码:

const name = 'Tony';
intl.get('HELLO', { name }).defaultMessage(`Hello, ${name}`); // "Hello, Tony"

或d简称:

const name = 'Tony';
intl.get('HELLO', { name }).d(`Hello, ${name}`); // "Hello, Tony"

并且getHTML还支持默认消息。

const name = 'Tony';
intl.getHTML('HELLO').d(<div>Hello, {name}</div>) // React.Element with "<div>Hello, Tony</div>"

HTML消息

get方法返回字符串消息。对于HTML消息,请getHTML改用。例如,

语言环境数据:

{ "TIP": "This is <span style='color:red'>HTML</span>" }

JS代码:

intl.getHTML('TIP'); // {React.Element}

帮手

react-intl-universal提供了一个实用程序,可帮助开发人员确定用户的currentLocale。作为正在运行的示例,当用户选择新的语言环境时,它将重定向用户新的位置,例如http://localhost:3000?lang=en-US。然后,我们可以使用intl.determineLocale从URL获取语言环境。它还可以支持通过cookie,localStorage和浏览器默认语言确定用户的语言环境。有关更多详细信息,请参阅API部分。

API定义

  /**
   * Initialize properties and load CLDR locale data according to currentLocale
   * @param {Object} options
   * @param {string} options.escapeHtml To escape html. Default value is true.
   * @param {string} options.currentLocale Current locale such as 'en-US'
   * @param {Object} options.locales App locale data like {"en-US":{"key1":"value1"},"zh-CN":{"key1":"值1"}}
   * @param {Object} options.warningHandler Ability to accumulate missing messages using third party services. See https://github.com/alibaba/react-intl-universal/releases/tag/1.11.1
   * @param {string} options.fallbackLocale Fallback locale such as 'zh-CN' to use if a key is not found in the current locale
   * @returns {Promise}
   */
  init(options)


  /**
   * Load more locales after init
   * @param {Object} locales App locale data 
   */
  load(locales)


  /**
   * Get the formatted message by key
   * @param {string} key The string representing key in locale data file
   * @param {Object} variables Variables in message
   * @returns {string} message
   */
  get(key, variables)

  /**
   * Get the formatted html message by key.
   * @param {string} key The string representing key in locale data file
   * @param {Object} variables Variables in message
   * @returns {React.Element} message
  */
  getHTML(key, options)

  /**
   * Helper: determine user's locale via URL, cookie, and browser's language.
   * You may not this API, if you have other rules to determine user's locale.
   * @param {string} options.urlLocaleKey URL's query Key to determine locale. Example: if URL=http://localhost?lang=en-US, then set it 'lang'
   * @param {string} options.cookieLocaleKey Cookie's Key to determine locale. Example: if cookie=lang:en-US, then set it 'lang'
   * @param {string} options.localStorageLocaleKey LocalStorage's Key to determine locale such as 'lang'
   * @returns {string} determined locale such as 'en-US'
   */
  determineLocale(options)

  /**
   * Get the inital options 
   * @returns {Object} options includes currentLocale and locales
   */
  getInitOptions()

与react-intl的兼容性

如问题Mirror react-intl API中所述,使人们可以将现有的React项目从react-intl切换到react-intl-universal。我们提供以下两个兼容的API。

  /**
   * As same as get(...) API
   * @param {Object} options 
   * @param {string} options.id 
   * @param {string} options.defaultMessage
   * @param {Object} variables Variables in message
   * @returns {string} message
  */
  formatMessage(options, variables)
  /**
   * As same as getHTML(...) API
   * @param {Object} options 
   * @param {string} options.id 
   * @param {React.Element} options.defaultMessage
   * @param {Object} variables Variables in message
   * @returns {React.Element} message
  */
  formatHTMLMessage(options, variables)

例如,formatMessageAPI

const name = 'Tony';
intl.formatMessage({ id:'hello', defaultMessage: `Hello, ${name}`}, {name});

相当于getAPI

const name = 'Tony';
intl.get('hello', {name}).d(`Hello, ${name}`);

formatHTMLMessageAPI

const name = 'Tony';
intl.formatHTMLMessage({ id:'hello', defaultMessage: <div>Hello</div>}, {name});

相当于getHTMLAPI

const name = 'Tony';
intl.getHTML('hello', {name}).d(<div>Hello</div>);

浏览器兼容性

在使用react-intl-universal之前,您需要在HTML中包含以下脚本以支持较旧的浏览器。

<!--[if lt IE 9]>
<script src="//f.alicdn.com/es5-shim/4.5.7/es5-shim.min.js"></script>
<![endif]-->
<script>
if(typeof Promise!=="function"){document.write('<script src="//f.alicdn.com/es6-shim/0.35.1/??es6-shim.min.js,es6-sham.min.js"><\/script>')}
</script>
 类似资料: