Предварительный просмотр эффекта
Шаги интернационализации React Intl
- Создание интернационализированных файлов ресурсов
- Доступ к интернационализированным ресурсам по языку
- Ввести локальные данные react-intl
- Создайте компонент контекста интернационализации LocaleProvider.
- Создать компонент контекста интернационализации react-intl
- Используйте компоненты и API react-intl для международного развития
1. Создайте интернационализированный файл ресурсов
В настоящее время мы управляем файлами ресурсов в папке src/locales:
.
├── en-US.js
├── en-US.messages.js
├── zh-Hans.js
└── zh-Hans.messages.js
*.messages.js — это наш файл ресурсов (здесь мы используем формат js, вы также можете использовать json и т. д.), он возвращает объект, ключ — это идентификатор, который мы используем для перевода, значение — это перевод конкретного языка , а содержание:
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 инкапсулирует содержимое, необходимое для компонентов контекста интернационализации, таких как сообщения и локаль:
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;
С помощью этих файлов ресурсов и связанных пакетов мы можемLocaleProvider
иInltProvider
используется в.
2. Загружайте интернационализированные ресурсы в соответствии с языком
На предыдущем шаге мы создали интернационализированные файлы ресурсов для разных языковых версий.Нам также нужна функция для загрузки соответствующих файлов ресурсов в соответствии с языком:
/**
* 获取国际化资源文件
*
* @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
import { addLocaleData } from 'react-intl';
...
render() {
const appLocale = getLocale('en-US');
addLocaleData(...appLocale.data);
...
}
react-intl нужны специальные локальные данные при интернационализации, в основном при переводе относительного времени, например, вчера, сегодня, завтра, несколько минут назад, несколько месяцев назад и так далее.
мы проходимaddLocaleData
Этот метод загружает соответствующий контент, и вы можете загрузить необходимые данные локали в соответствии с реальной ситуацией.
4. Создайте компонент контекста интернационализации 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. Создайте компонент контекста интернационализации react-intl
Чтобы иметь возможность использовать react-intl для интернационализации, как и такие фреймворки, как redux, нам нужен компонент провайдера для предоставления контекста интернационализации.
...
import { addLocaleData, IntlProvider } from 'react-intl';
import LocaleProvider from '@/components/locale-provider';
import Home from '@/views/home';
...
render() {
// 根据语言获取国际化资源
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 有三个配置参数:
locale, <object>, 国际化资源.
IntlProvider 有三个配置参数:
locale, <string>, 语言标记,例如 'zh-CN' 'en-US'
messages, <object>, 国际化所需的 key-value 对象
formats, <object>, 自定义 format,比如日期格式、货币等
четко определенныйIntlProvider
После этого мы можем использовать API или компоненты, которые он предоставляет для интернационализации на странице.
6. Используйте компоненты и API react-intl
react-intl предоставляет богатые компоненты и API для завершения интернационализации частей страницы.
форматирование строки
a. <FormattedMessage />
Этот компонент используется для форматирования строк и является наиболее часто используемым компонентом из всех компонентов. Помимо вывода простых строк на разных языках в соответствии с конфигурацией, также возможен вывод сложных строк, содержащих динамически изменяющиеся параметры, конкретное использование которых будет описано в следующих примерах.
Например, мы прописали в конфигурационном файле *.message.js следующее:
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} 是一个用于构建用户界面的 JAVASCRIPT 库。"
description="{name} 是什么?"
/>
- id относится к имени атрибута этой строки в файле конфигурации
- описание относится к описанию строки, заменяемой этой позицией, что удобно для сопровождения кода, если его не написать, то это не повлияет на результат вывода.
- defaultMessage Значение вывода по умолчанию, когда идентификатор не найден в файле конфигурации локали.
- tagName Фактически сгенерированный тег, по умолчанию
span
- значения динамического параметра.Формат объектный
Результат вывода:
<p>React, a JavaScript library for building user interfaces.</p>
b. <FormattedHTMLMessage />
Использование этого компонента точно такое же, с той лишь разницей, что выходная строка может содержать теги HTML.
дата и время
a. <FormattedDate />
Для форматирования дат можно преобразовать метку времени в формат даты на разных языках.
Передайте метку времени в качестве параметра:
<FormattedDate
value={new Date(1459832991883)}
/>
Выходной результат:
<!-- 英文 -->
<span>4/5/2016</span>
<!-- 中文 -->
<span>2016/5/4</span>
b. <FormattedTime>
Используется для форматирования времени, эффект такой же, как<FormattedDate />
сходство.
Передайте метку времени в качестве параметра:
<FormattedTime
value={new Date(1459832991883)}
/>
Выходной результат:
<!-- 英文 -->
<span>1:09 AM</span>
<!-- 中文 -->
<span>上午1:09</span>
c. <FormattedRelative />
Этот компонент может отображать взаимосвязь между отметкой времени, переданной в компонент, и текущим временем, например «10 минут назад».
Передайте метку времени в качестве параметра:
<FormattedRelative
value={Date.now()}
/>
Выходной результат:
<!-- 英文 =>> 运行时的输出结果: -->
<span>now</span>
<!-- 英文 =>> 10秒之后的输出结果: -->
<span>10 seconds ago</span>
<!-- 英文 =>> 1分钟之后的输出结果: -->
<span>1 minute ago</span>
<!-- 中文 =>> 运行时的输出结果: -->
<span>现在</span>
<!-- 中文 =>> 10秒之后的输出结果: -->
<span>10秒前</span>
<!-- 中文 =>> 1分钟之后的输出结果: -->
<span>1分钟前</span>
цифровой квантификатор
a. <FormattedPlural />
Этот компонент можно использовать для форматирования квантификаторов. В контексте китайского языка он на самом деле не очень полезен. Например, если мы говорим «куриная ножка», то квантификатор «а», а если мы говорим «две куриные ножки», квантификатор по-прежнему 'а', чего не произойдет. Разнообразие. Но в англоязычной среде при описании яблока квантором является яблоко.Когда количество яблок равно двум, оно станет яблоками.Функция этого компонента здесь.
Среди параметров, передаваемых в компонент, значение — это количество, а остальные — это квантификаторы, соответствующие разным количествам. Квантификаторы, которые фактически могут быть переданы компонентам, включают ноль, один, два, несколько, много, другие, которые охватывают все случаи.
комбинировать<FormattedMessage />
использовать:
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>
Выходной результат:
<!-- 英文 -->
<p>You have 10 new notifications</p>
<p>You have 1 notification</p>
<!-- 中文 -->
<p>你有10条新信息</p>
<p>你有1条新信息</p>
b. <FormattedNumber />
Основная цель этого компонента — пометить строку чисел запятыми. Например, число 10 000 должно быть 1 0000 в среде китайского языка, которая представляет собой запятую через каждые 4 цифры, и 10 000 в среде английского языка. запятая через каждые 3 цифры.
Передайте число в качестве параметра:
<FormattedNumber
value={1000}
/>
Выходной результат:
<span>1,000</span>
<FormattedNumber />
выходной процент
Передайте десятичное число в качестве параметра:
<FormattedNumber
value={0.5}
style="percent"
/>
Выходной результат:
<span>50%</span>
<FormattedNumber />
выходная валюта
Передайте число в качестве параметра:
// locale.formats.money.currency 是 /locales/*.js 国际化资源配置的货币信息。中文: 'CNY'; 英文: 'USD'
<FormattedNumber
value={123456.78}
style="currency"
currency={locale.formats.money.currency}
/>
Выходной результат:
<!-- 英文 -->
<span>$123,456.78</span>
<!-- 中文 -->
<span>¥123,456.78</span>
Примечание: в случае китайского языка запятая также добавляется каждые 3 цифры.Конкретная причина подробно описана.Если вы знаете причину, пожалуйста, дайте мне знать.
интернационализация компонента
1. Создайте функцию для получения ресурсов интернационализации контекста.
/**
* 获取 组件的语言配置
*
* @param {any} props 属性
* @param {any} context 上下文
* @param {any} componentName 组件名. 对应 context.locale.messages 中的 key 值
* @param {any} getDefaultLocale
*/
function getComponentLocale(props, context, componentName, getDefaultLocale) {
let locale = {};
// 如果 context 上下文中有多语言配置. 则取 context 上下文中的多语言值.
// 否则, 取默认值的多语言值.
if (context && context.locale && context.locale.messages[componentName]) {
locale = context.locale.messages[componentName];
} else {
const defaultLocale = getDefaultLocale();
locale = defaultLocale.default || defaultLocale;
}
let result = {
...locale,
};
// 如果属性有语言配置项, 则合并.
if (props.locale) {
result = {
...result,
...props.locale,
};
if (props.locale.lang) {
result.lang = {
...locale.lang,
...props.locale.lang,
};
}
}
return result;
}
2. Создайте интернационализированные компоненты
...
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>
);
}
}
Приложение к спецификации интернационализации
Спецификация React Intl Write
- defaultMessage должен быть заполнен, и defaultMessage используется как китайский перевод
- идентификатор не должен повторяться
- При использовании intl.formatMessage() вы должны использовать defineMessages для предопределения сообщений.
исходный код
весь проектисходный код