@alicloud/console-components-intl
v1.0.20
Published
React component for Alibaba Cloud.
Downloads
115
Readme
@alicloud/console-components-intl
帮助你的项目快速应用国际化和本地化。前端开发者在编写代码的时候,不再耦合于某一语种,而是依赖于一个“文案 key”,而文案id=>文案内容
的配置在顶层统一完成。
安装
$ yarn add @alicloud/console-components-intl
用法说明
- 正常用法:使用 intl 单例。你在项目的各个地方
import intl from '@alicloud/console-components-intl'
得到的都是同一个 intl 实例。方便文案的全局共享。 - 进阶用法:自己创建 intl 实例。各个 intl 实例可以有自己的文案字典,让你更加精确地控制文案的作用区域。
使用 intl 单例
你在项目的各个地方import intl from '@alicloud/console-components-intl'
得到的都是同一个 intl 实例。方便文案的全局共享。
- 在项目入口初始化文案
import intl from '@alicloud/console-components-intl'
// 通过任何方式拿到当前用户的语言文案,比如由服务端将文案注入到window.messages中
const messages = {
'app.title': 'English title',
}
intl.set({ messages })
- 在顶层组件外部包裹一层 HOC
import { render } from 'react-dom'
import intl from '@alicloud/console-components-intl'
const App = intl.withProvider()(OriginApp)
render(<App />, document.getElementById('app'))
- 在项目模块中使用 intl 进行国际化声明
import intl from '@alicloud/console-components-intl'
const Title = () => <h1>{intl('app.title')}</h1>
export default Title
在字典定义中,在文案中可以用 {
}
声明参数,并且在使用intl
解析文案时传入参数。关于更多的语法说明,可以参考ICU Message Syntax。下面有使用例子。
注意到,有了 intl 组件以后,前端开发者在编写代码的时候,不再耦合于某一语种,而是依赖于一个“文案 key”,而文案id=>文案内容
的配置在顶层统一完成。
自己创建 intl 实例
如果你想要更加精确地控制文案的作用区域,你不应该使用@alicloud/console-components-intl
给你创建好的顶层实例,而是自己创建 intl 实例。
import { reactIntlFactory } from '@alicloud/console-components-intl'
const intl = reactIntlFactory()
使用示例
以下每个 demo 都使用了reactIntlFactory
来创建独立的 intl 实例,避免 demo 之间的文案相互影响。
$XView $XView $XView $XView $XView $XView
API
intl.set
设定国际化的基本环境变量
intl.set(data: IntlData, options: IntlOptions): void
IntlData
IntlData = {
messages: Object,
locale: String,
}
- messages: 国际化需要的字典描述对象
- locale: BCP-47 locale 字符串。比如简体中文是
zh-Hans-CN
,英文是en-US
。
IntlOptions
IntlOptions = {
determineLocale: DetermineLocale,
}
determineLocale: 确定 locale 自动获取的方式。无特殊需求无需了解。
DetermineLocale = { globalIdentifier?: String|Array<String>, cookie?: String|Array<String>, html?: Boolean, navigator?: Boolean, fallback?: String, }
- globalIdentifier: 从全局变量中获取 locale,这个获取逻辑是优先级最高的,如果该值是一个字符串,将会将该字符串作为全局变量的声明引用进行 locale 取值;如果该值为一个字符串数组,则会依次将数组中的字符串作为全局变量的声明顺序进行 locale 的取值,直到取得有效的值。如果 globalIdentifier 设置的值可以获取有效的 locale,则不再执行
cookie
,html
,navigator
,fallback
的相关获取逻辑 - cookie: 从 cookie 中获取 locale,当 globalIdentifier 未获取到有效的值时,将执行和 cookie 相关的获取处理逻辑。如果该值是一个字符串,将会将该字符串作为 cookie 的 key 进行 locale 取值;如果该值为一个字符串数组,则会依次将数组中的字符串作为 cookie 的 key 顺序进行 locale 的取值,直到取得有效的值。如果 cookie 设置的值可以获取有效的 locale,则不再执行
html
,navigator
,fallback
的相关获取逻辑 - html: 从 html 标签中获取语言信息(lang),当 globalIdentifier 和 cookie 都未获取到有效的 locale 值,且 html 的值为真值(truthy value),则尝试从 html 标签中获取 lang 属性的值,如果可以获得有效的 lang 值,则将获取到的 lang 作为 locale 的值,不再执行后续的获取逻辑
- navigator: 从 navigator.language 获取语言信息,当前面的获取逻辑均为获取到有效的 locale 值,且 navigator 的值为真值,则尝试从浏览器对象 navigator.language 中获取语言信息,如果可以获得有效的 language 的值,并将其作为 locale 的值,不再执行后续的获取逻辑
- fallback: 如果从上述的获取逻辑中未去到任何有效的 locale 值,则将 fallback 指定的语言信息字符串作为当前的 locale 值
- globalIdentifier: 从全局变量中获取 locale,这个获取逻辑是优先级最高的,如果该值是一个字符串,将会将该字符串作为全局变量的声明引用进行 locale 取值;如果该值为一个字符串数组,则会依次将数组中的字符串作为全局变量的声明顺序进行 locale 的取值,直到取得有效的值。如果 globalIdentifier 设置的值可以获取有效的 locale,则不再执行
intl
输出字典对应 key 的信息
intl(key: String, values?: Object, preferString?: Boolean): String|ReactElement
初始化
首先我们先准备一个字典,并使用 intl.set
导入字典声明
locales/messages.js
export default {
'app.title': '国际化控制台',
'app.desc': '共有{count}个控制台使用了wind国际化功能',
'app.desc.html':
'共有<strong>{count, number}</strong>个控制台使用了wind国际化功能',
}
在字典定义中,变量可以用 {
}
进行声明,并且在使用时进行赋值,关于更多的语法说明,可以参考
initializer.js
import intl from '@alicloud/console-components-intl'
import messages from './locales/messages'
intl.set({ messages })
在入口文件处引用初始化文件
app.js
import React from 'react'
import { render } from 'react-dom'
import './initializer'
import App from './App'
render(<App />, document.getElementById('app'))
使用 intl 输出字典值
在 App 中的任意模块都可以使用 intl 方法输出字典值
Title.js
import intl from '@alicloud/console-components-intl'
const Title = () => <h1>{intl('app.title')}</h1>
export default Title
使用模板变量
Desc.js
import intl from '@alicloud/console-components-intl'
const Desc = ({ count }) => <mark>{intl('app.desc', { count })}</mark>
export default Desc
在变量中使用 React 组件
模板变量可以传入 React 组件,来完成定制化的渲染需求,让我们对 Desc.js
进行一些修改,让 count
变量接受一个组件
Desc.js
import intl from '@alicloud/console-components-intl'
const Desc = ({ count }) => (
<mark>
{intl('app.desc', {
count: <strong>{intl.number(count)}</strong>,
})}
</mark>
)
export default Desc
需要注意的是,如果字典中使用了 ICU 的格式化语法,如 I have {count, number} cats
,请不要在变量中传入组件
默认使用字符串作为国际化输出结果
与之前的 wind-intl
不同,使用 intl()
的返回结果默认是一个字符串,你可以在诸如 input.placeholder
等属性中直接使用
<Input placeholder={intl('app.title')} />
在以下两种情况下,使用 intl()
会返回一个 React 组件:
- 至少有一个变量值是 React 组件
- 强制指定
preferString
参数为false
intl.html
将带有 html 标签的字典值输出成一段 html,该方法将始终返回一个 React 组件
intl.html(key: String, value?: Object): ReactElement
输出带有 html 标签的字典值
DescHtml.js
import intl from '@alicloud/console-components-intl'
const DescHtml = ({ count }) => (
<mark>{intl.html('app.desc.html', { count })}</mark>
)
export default DescHtml
intl.date
将时间日期进行本地化输出
intl.date(date: Date, options?: DateTimePresetFormat|Intl.DateTimeFormatOptions): String
DateTimePresetFormat
DateTimePresetFormat = String(
'date',
'time',
'dateTime',
'dateTimeWithTimeZone'
)
Intl.DateTimeFormatOptions
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat
输出本地化的时间格式
CurrentDateTime.js
import intl from '@alicloud/console-components-intl'
const CurrentDateTime = () => <span>{intl.date(new Date())}</span>
export default CurrentDateTime
使用预设输出本地化的时间格式
@alicloud/console-components-intl
默认提供三种时间预设:
date
: 只输出日期time
: 只输出时间dateTime
: (default) 输出日期和时间dateTimeWithTimeZone
: 输出日期时间以及当前的时区
你可以以字符串的形式指定 intl.date()
的第二个参数,使用对应的预设方案
CurrentDateTime.js
import intl from '@alicloud/console-components-intl'
const CurrentDateTime = () => <span>{intl.date(new Date(), 'date')}</span>
export default CurrentDateTime
intl.number
将数字进行本地化输出
intl.number(value: Number, options?: Intl.NumberFormatOptions)
Intl.NumberFormatOptions
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat
输出本地化的数字格式
Counter.js
import intl from '@alicloud/console-components-intl'
const Counter = ({ count }) => <span>{intl.number(count)}</span>
export default Counter
intl.registerOnError
注册发生错误时的回调函数。在回调函数中,你可以获取到一些有用的上下文信息。
- 回调函数可以用于日志上报,从而你能及时发现线上的文案问题。
- 回调函数可以返回 fallback 的文案,从而你可以利用上下文信息来返回更合理的异常文案。
intl.registerOnError(onError: OnError)
type OnError = (errorInfo: {
code: ErrorCode
key?: string
ctx?: unknown
error?: any
}) => string | void
type ErrorCode =
| 'formatDate'
| 'formatNumber'
| 'formatMessage.messagesNotSetYet'
| 'formatMessage.notFound'
| 'formatMessage.invalidMessage'
| 'formatMessage.localeNotSet'
| 'formatMessage.formatError'
参考以下 demo: $XView