react-intl實(shí)現(xiàn)React國際化多語言的方法
本文主要介紹了react-intl實(shí)現(xiàn)React國際化多語言的方法,分享給大家,具體如下:
效果預(yù)覽

React Intl 國際化步驟
- 創(chuàng)建國際化資源文件
- 根據(jù)語言獲取國際化資源
- 引入 react-intl 的 local data
- 創(chuàng)建 LocaleProvider 國際化上下文組件
- 創(chuàng)建 react-intl 國際化上下文組件
- 使用 react-intl's components & apis,進(jìn)行國際化開發(fā)
1. 創(chuàng)建國際化資源文件
目前我們管理資源文件的方式是在 src/locales 文件夾下:
. ├── en-US.js ├── en-US.messages.js ├── zh-Hans.js └── zh-Hans.messages.js
*.messages.js 是我們的資源文件(這里我們采用了 js 格式,你也可以使用 json 等等),返回的是一個對象,key 為我們翻譯用的 id,value 為具體語言的翻譯,內(nèi)容是:
export default {
'page.localeProvider.react': '{ name }, a JavaScript library for building user interfaces.',
'page.localeProvider.react.html': '<p>{ name } makes it painless to create interactive UIs. Design simple views for each state in your application, and { name } will efficiently update and render just the right components when your data changes.</p><p>Declarative views make your code more predictable and easier to debug.</p>',
'page.localeProvider.unreadCount': 'You have {unreadCount} new {notifications}',
'page.localeProvider.title.date': 'Current date: ',
'page.localeProvider.title.time': 'Current time: ',
'page.localeProvider.title.relative': 'Relative current time: ',
'page.localeProvider.title.number': 'Comma number: ',
'page.localeProvider.title.price': 'Price: ',
'page.localeProvider.title.percent': 'Percent: ',
};
en-US.js 文件封裝了 messages、locale 等國際化上下文組件需要的內(nèi)容:
import appLocaleData from 'react-intl/locale-data/en';
// 引入組件多語言
import paginationLocale from '@/components/pagination/locales/en-US';
import messages from './en-US.messages';
window.appLocale = {
// 合并所有 messages, 加入組件的 messages
messages: Object.assign({}, messages, {
Pagination: paginationLocale,
}),
// locale
locale: 'en-US',
// react-intl locale-data
data: appLocaleData,
// 自定義 formates
formats: {
date: {
normal: {
hour12: false,
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
},
},
// 貨幣
money: {
currency: 'USD',
},
},
};
export default window.appLocale;
有了這些資源文件以及相關(guān)的封裝之后,我們就可以在 LocaleProvider 和 InltProvider 中使用了。
2. 根據(jù)語言加載國際化資源
上一步我們創(chuàng)建了不同語言版本的國際化資源文件,我們還需要一個函數(shù)能夠根據(jù)語言,加載對應(yīng)的資源文件:
/**
* 獲取國際化資源文件
*
* @param {any} lang
* @returns
*/
function getLocale(lang) {
let result = {};
switch (lang) {
case 'zh-CN':
result = require('./locales/zh-Hans');
break;
case 'en-US':
result = require('./locales/en-US');
break;
default:
result = require('./locales/zh-Hans');
}
return result.default || result;
}
3. 引入 react-intl 的 local data
import { addLocaleData } from 'react-intl';
...
render() {
const appLocale = getLocale('en-US');
addLocaleData(...appLocale.data);
...
}
react-intl 在做國際化的時候需要一些特有的 local data,主要是進(jìn)行相對時間翻譯時,比如昨天、今天、明天、幾分鐘前、幾個月前之類的。我們通過 addLocaleData 這個方法加載相關(guān)內(nèi)容,大家可以根據(jù)實(shí)際情況加載需要的 locale-data。
4. 創(chuàng)建 LocaleProvider 國際化上下文組件
為了組件能夠國際化資源信息,我們需要一個 LocaleProvider 組件,用它來提供國際化的上下文,具體用法:
export default class LocaleProvider extends React.Component {
static propTypes = {
children: PropTypes.any,
locale: PropTypes.object,
};
static childContextTypes = {
// 語言信息
locale: PropTypes.object,
};
getChildContext() {
return {
locale: {
...this.props.locale,
},
};
}
render() {
return React.Children.only(this.props.children);
}
}
5. 創(chuàng)建 react-intl 國際化上下文組件
為了能夠使用 react-intl 進(jìn)行國際化,跟 redux 這些框架一樣,我們需要一個 Provider Component,用它來提供國際化的上下文,具體用法:
...
import { addLocaleData, IntlProvider } from 'react-intl';
import LocaleProvider from '@/components/locale-provider';
import Home from '@/views/home';
...
render() {
// 根據(jù)語言獲取國際化資源
const appLocale = getLocale('en-US');
addLocaleData(...appLocale.data);
return (
<LocaleProvider locale={appLocale}>
<IntlProvider
locale={appLocale.locale}
messages={appLocale.messages}
formats={appLocale.formats}
>
<Home />
</IntlProvider>
</LocaleProvider>
);
}
LocaleProvider 有三個配置參數(shù):
- locale, <object>, 國際化資源.
IntlProvider 有三個配置參數(shù):
- locale, <string>, 語言標(biāo)記,例如 'zh-CN' 'en-US'
- messages, <object>, 國際化所需的 key-value 對象
- formats, <object>, 自定義 format,比如日期格式、貨幣等
在定義好 IntlProvider 之后,我們就可以在頁面使用它提供的 api 或者組件來進(jìn)行國際化了。
6. 使用 react-intl's components & apis
react-intl 提供了豐富的組件和 api 來完成頁面部分的國際化。
字符串的格式化
a. <FormattedMessage /> 這個組件用于格式化字符串,是所有的組件中使用頻率最高的組件。除了可以根據(jù)配置輸出不同語言的簡單字符串之外,還可以輸出包含動態(tài)變化的參數(shù)的復(fù)雜字符串,具體的用法在后面的例子中會慢慢敘述。
比如我們在 *.message.js 配置文件中寫了如下內(nèi)容:
export default {
'page.localeProvider.react': '{ name }, a JavaScript library for building user interfaces.',
};
使用這個組件的時候,我們這么寫:
<FormattedMessage
tagName="p"
id="page.localeProvider.react"
values={{
name: 'React',
}}
defaultMessage="{name} 是一個用于構(gòu)建用戶界面的 JAVASCRIPT 庫。"
description="{name} 是什么?"
/>
- id 指代的是這個字符串在配置文件中的屬性名
- description 指的是對于這個位置替代的字符串的描述,便于維護(hù)代碼,不寫的話也不會影響輸出的結(jié)果
- defaultMessage 當(dāng)在locale配置文件中沒有找到這個id的時候,輸出的默認(rèn)值
- tagName 實(shí)際生成的標(biāo)簽,默認(rèn)是 span
- values 動態(tài)參數(shù). 格式為對象
輸出的結(jié)果:
<p>React, a JavaScript library for building user interfaces.</p>
b. <FormattedHTMLMessage />這個組件的用法和完全相同,唯一的不同就是輸出的字符串可以包含HTML標(biāo)簽。
日期時間
a. <FormattedDate /> 用于格式化日期,能夠?qū)⒁粋€時間戳格式化成不同語言中的日期格式。
傳入時間戳作為參數(shù):
<FormattedDate
value={new Date(1459832991883)}
/>
輸出結(jié)果:
<!-- 英文 -->
<span>4/5/2016</span><!-- 中文 -->
<span>2016/5/4</span>
b. <FormattedTime> 用于格式化時間,效果與<FormattedDate />相似。
傳入時間戳作為參數(shù):
<FormattedTime
value={new Date(1459832991883)}
/>
輸出結(jié)果:
<!-- 英文 -->
<span>1:09 AM</span><!-- 中文 -->
<span>上午1:09</span>
c. <FormattedRelative /> 通過這個組件可以顯示傳入組件的某個時間戳和當(dāng)前時間的關(guān)系,比如“10 minutes ago”。
傳入時間戳作為參數(shù):
<FormattedRelative
value={Date.now()}
/>
輸出結(jié)果:
<!-- 英文 =>> 運(yùn)行時的輸出結(jié)果: -->
<span>now</span><!-- 英文 =>> 10秒之后的輸出結(jié)果: -->
<span>10 seconds ago</span><!-- 英文 =>> 1分鐘之后的輸出結(jié)果: -->
<span>1 minute ago</span><!-- 中文 =>> 運(yùn)行時的輸出結(jié)果: -->
<span>現(xiàn)在</span><!-- 中文 =>> 10秒之后的輸出結(jié)果: -->
<span>10秒前</span><!-- 中文 =>> 1分鐘之后的輸出結(jié)果: -->
<span>1分鐘前</span>
數(shù)字量詞
a. <FormattedPlural /> 這個組件可用于格式化量詞,在中文的語境中,其實(shí)不太會用得到,比如我們說一個雞腿,那么量詞就是‘個',我們說兩個雞腿,量詞還是‘個',不會發(fā)生變化。但是在英文的語言環(huán)境中,描述一個蘋果的時候,量詞是apple,當(dāng)蘋果數(shù)量為兩個時,就會變成apples,這個組件的作用就在于此。
傳入組件的參數(shù)中,value為數(shù)量,其他的為不同數(shù)量時對應(yīng)的量詞,在下面的例子中,一個的時候量詞為message,兩個的時候量詞為messages。實(shí)際上可以傳入組件的量詞包括 zero, one, two, few, many, other 已經(jīng)涵蓋了所有的情況。
結(jié)合 <FormattedMessage />運(yùn)用:
const unreadCount = 10;
const unreadCount2 = 1;
...
<p>
<FormattedMessage
id="page.localeProvider.unreadCount"
defaultMessage={'你有{ unreadCount }條新信息'}
values={{
unreadCount: (
<strong
style={{
color: '#f30',
fontWeight: 'normal',
}}
>
<FormattedNumber
value={unreadCount}
/>
</strong>
),
notifications: (
<FormattedPlural
value={unreadCount}
one="notification"
other="notifications"
/>
),
}}
/>
</p>
<p>
<FormattedMessage
id="page.localeProvider.unreadCount"
defaultMessage={'你有{ unreadCount2 }條新信息'}
values={{
unreadCount: (
<strong
style={{
color: '#f30',
fontWeight: 'normal',
}}
>
<FormattedNumber
value={unreadCount2}
/>
</strong>
),
notifications: (
<FormattedPlural
value={unreadCount2}
one="notification"
other="notifications"
/>
),
}}
/>
</p>
輸出結(jié)果:
<!-- 英文 -->
<p>You have 10 new notifications</p>
<p>You have 1 notification</p><!-- 中文 -->
<p>你有10條新信息</p>
<p>你有1條新信息</p>
b. <FormattedNumber /> 這個組件最主要的用途是用來給一串?dāng)?shù)字標(biāo)逗號,比如10000這個數(shù)字,在中文的語言環(huán)境中應(yīng)該是1,0000,是每隔4位加一個逗號,而在英語的環(huán)境中是10,000,每隔3位加一個逗號。
傳入數(shù)字作為參數(shù):
<FormattedNumber
value={1000}
/>
輸出結(jié)果:
<span>1,000</span>
<FormattedNumber /> 輸出百分比
傳入小數(shù)作為參數(shù):
<FormattedNumber
value={0.5}
style="percent"
/>
輸出結(jié)果:
<span>50%</span>
<FormattedNumber /> 輸出貨幣
傳入數(shù)字作為參數(shù):
// locale.formats.money.currency 是 /locales/*.js 國際化資源配置的貨幣信息。中文: 'CNY'; 英文: 'USD'
<FormattedNumber
value={123456.78}
style="currency"
currency={locale.formats.money.currency}
/>
輸出結(jié)果:
<!-- 英文 -->
<span>$123,456.78</span><!-- 中文 -->
<span>¥123,456.78</span>
注:項(xiàng)目在中文情況下也是每隔3位加一個逗號,具體原因詳,如果有知道原因的請告知。
組件國際化
1. 創(chuàng)建獲取上下文國際化資源函數(shù)
/**
* 獲取 組件的語言配置
*
* @param {any} props 屬性
* @param {any} context 上下文
* @param {any} componentName 組件名. 對應(yīng) context.locale.messages 中的 key 值
* @param {any} getDefaultLocale
*/
function getComponentLocale(props, context, componentName, getDefaultLocale) {
let locale = {};
// 如果 context 上下文中有多語言配置. 則取 context 上下文中的多語言值.
// 否則, 取默認(rèn)值的多語言值.
if (context && context.locale && context.locale.messages[componentName]) {
locale = context.locale.messages[componentName];
} else {
const defaultLocale = getDefaultLocale();
locale = defaultLocale.default || defaultLocale;
}
let result = {
...locale,
};
// 如果屬性有語言配置項(xiàng), 則合并.
if (props.locale) {
result = {
...result,
...props.locale,
};
if (props.locale.lang) {
result.lang = {
...locale.lang,
...props.locale.lang,
};
}
}
return result;
}
2. 創(chuàng)建國際化的組件
...
import { getComponentLocale } from '../_utils/getLocale';
...
export default class Pagination extends React.Component {
// context 上下文
static contextTypes = {
locale: PropTypes.object,
};
render() {
const currentlocale = getComponentLocale(this.props, this.context, 'Pagination', () => {
require('./locales/zh-CN');
});
return (
<div className="pagination">
<div className="pagination__wrapper">
<div className="pagination__button__prev">
<a>{currentlocale.prevText}</a>
</div>
<div className="pagination__button__next">
<a>{currentlocale.nextText}</a>
</div>
</div>
</div>
);
}
}
國際化規(guī)范附錄
React Intl 編寫規(guī)范
- 必須填寫 defaultMessage,并將 defaultMessage 作為中文翻譯
- id 不得重復(fù)
- 在使用 intl.formatMessage() 時,必須使用 defineMessages,預(yù)定義消息
源碼
整個項(xiàng)目源碼
資料
到此這篇關(guān)于react-intl實(shí)現(xiàn)React國際化多語言的方法的文章就介紹到這了,更多相關(guān)React國際化多語言內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
react-native 圓弧拖動進(jìn)度條實(shí)現(xiàn)的示例代碼
本篇文章主要介紹了react-native 圓弧拖動進(jìn)度條實(shí)現(xiàn)的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-04-04
React+umi+typeScript創(chuàng)建項(xiàng)目的過程
這篇文章主要介紹了React+umi+typeScript創(chuàng)建項(xiàng)目的過程,結(jié)合代碼介紹了項(xiàng)目框架搭建的方式,本文給大家講解的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-02-02
React中setState/useState的使用方法詳細(xì)介紹
這篇文章主要介紹了React中setState/useState的使用方法,useState 和 setState 在React開發(fā)過程中 使用很頻繁,但很多人都停留在簡單的使用階段,并沒有正在了解它們的執(zhí)行機(jī)制2023-04-04
react-draggable實(shí)現(xiàn)拖拽功能實(shí)例詳解
這篇文章主要給大家介紹了關(guān)于react-draggable實(shí)現(xiàn)拖拽功能的相關(guān)資料,React-Draggable一個使元素可拖動的簡單組件,文中通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08
React實(shí)現(xiàn)響應(yīng)式布局的最佳實(shí)踐
在當(dāng)今的前端開發(fā)中,響應(yīng)式設(shè)計(jì)已經(jīng)成為必不可少的部分,隨著各種設(shè)備的出現(xiàn),確保我們的網(wǎng)頁在不同屏幕尺寸上展示良好,已經(jīng)成為開發(fā)者的首要任務(wù)之一,本文將介紹如何在React中實(shí)現(xiàn)響應(yīng)式布局,提供一些最佳實(shí)踐和示例代碼,幫助大家更好地理解這一概念2025-02-02

