在 React 项目中使用 React-intl 实现多语言支持
组件替代,最后通过简单的配置实现语言的国际化,那我们就用React-intl吧。
注意:本文说的是用法,源码我也没有拜读过,太深的东西去github给作者留言吧。
包裹在需要语言国际化的组建的最外层,为包含在其中的所有组建提供包含id和字符串的键值对。(如:"homepage.title":"Hommily";)
日期时间
a. 用于格式化日期,能够将一个时间戳格式化成不同语言中的日期格式。
传入时间戳作为参数:
输出结果:
4/5/2016
b. 用于格式化时间,效果与相似。
传入时间戳作为参数:
输出结果:
1:09 AM
c. 通过这个组件可以显示传入组件的某个时间戳和当前时间的关系,比如 “ 10 minutes ago"。
传入时间戳作为参数:
输出结果:
now
10秒之后的输出结果:
10 seconds ago
1分钟之后的输出结果:
1 minute ago
数字量词
a. 这个组件最主要的用途是用来给一串数字标逗号,比如10000这个数字,在中文的语言环境中应该是1,0000,是每隔4位加一个逗号,而在英语的环境中是10,000,每隔3位加一个逗号。
传入数字作为参数:
输出结果:
1,000
b. 这个组件可用于格式化量词,在中文的语境中,其实不太会用得到,比如我们说一个鸡腿,那么量词就是‘个’,我们说两个鸡腿,量词还是‘个’,不会发生变化。但是在英文的语言环境中,描述一个苹果的时候,量词是apple,当苹果数量为两个时,就会变成apples,这个组件的作用就在于此。
传入组件的参数中,value为数量,其他的为不同数量时对应的量词,在下面的例子中,一个的时候量词为message,两个的时候量词为messages。实际上可以传入组件的量词包括 zero, one, two, few, many, other 已经涵盖了所有的情况。
传入组件的量词参数可以是一个字符串,也可以是一个组件,我们可以选择传入组件,就可以实现量词的不同语言的切换。
输出结果:
messages
字符串的格式化
a. 这个组件用于格式化字符串,是所有的组件中使用频率最高的组件,因为基本上,UI上面的每一个字符串都应该用这个组件替代。这个组件的功能丰富,除了可以根据配置输出不同语言的简单字符串之外,还可以输出包含动态变化的参数的复杂字符串,具体的用法在后面的例子中会慢慢叙述。
比如我们在locale配置文件中写了如下内容:
const app = { greeting:'Hello Howard!",}export default app;
使用这个组件的时候,我们这么写:
id指代的是这个字符串在locale配置文件中的属性名,description指的是对于这个位置替代的字符串的描述,便于维护代码,不写的话也不会影响输出的结果,当在locale配置文件中没有找到这个id的时候,输出的结果就是defaultMessage的值。
输出的结果:
Hello, Howard!
b. 这个组件的用法和完全相同,唯一的不同就是输出的字符串可以包含HTML标签,但是官方不太推荐使用这个方法,如果可以想办法用的话,就不应该使用这个组件,我揣测应该是性能方面不如,这个组件的用法我就不举例了。
Well,到此为止,已经把React-intl提供的所有组件介绍完了,下面就给大家介绍一下具体如何去使用吧。
React-intl 使用步骤
(本文例子运行在OSX环境,Window操作方法的终端在安装的时候要注意用管理员身份运行)
1. 安装React-intl
假设你已经在你的系统中安装了node.js和npm,如果你还不知道这两个是什么东西,请自行百度,对,在百度都能找到答案。
打开终端,进入项目根目录,输入以下指令安装React-intl:
npm install react-intl -save
注意:为了兼容Safari各个版本,需要同时安装 intl,intl在大部分的『现代』浏览器中是默认自带的,但是Safari和IE11以下的版本就没有了,这里需要留个心眼。
安装intl需要在终端中输入以下指令:
npm install intl --save
这里还有一个注意:由于React-intl的每一个组件的使用方法大同小异,和ReactJS的语法完全一致,所以我就仅仅描述如何使用这个组件的用法,借此抛砖引玉,相信看完之后已经足够帮助你迅速的去使用这个开源框架了。
2. 引用React-intl
import { FormattedMessage } from 'react-intl';
由于我使用的是ES6 的语法,所以是支持直接引用组件的。你当然可以使用ES5的方式引用,但是,这样有前途么?
require ReactIntl from 'react-intl';
3. 创建locale配置文件
这里,我们将文件命名为zh_CN.js和en_US.js,代表中文和美式英语的配置包。
在zh_CN.js编写如下代码:
export const zh_CN = { hello:"你好,方浩!", superHello:"你好,{ someone } !" }
在en_US.js编写如下代码:
export const en_US = { hello:"Hello, Howard!", superHello:"Hello, { someone } !" }
于是,我们就创建好了locale文件,但是,在实际的项目中配置文件不会这么简单,您可能需要根据业务需求按照不同的页面或者不同的功能块创建不同的文件树,然后用模块化的方法将不同的配置文件进行组织,已达成你的目标,这里我也就没能力逼逼太多了。
你可能想问,{ someone } 是什么鬼?其实悟性高一些的话就应该已经猜到,这个应该就是前面提到过的在字符串中插入动态参数的用法,事实上也是这样的。
4. 使用
使用 组件包裹住需要您需要进行语言国际化的组件,用法和React-redux的差不多,当 包裹住某个组件的时候,这个组件本身和组件内部包含的子组件就可以获得所有React-intl提供的接口以及在 中引入的locale配置文件的内容。
import React from 'react';import { render } from 'react-dom';//引入locale配置文件,具体路径根据实际情况填写import zh_CN from './zh_CN';import en-US from './en-US';//如果浏览器没有自带intl,则需要在使用npm安装intl之后添加如下代码import intl from 'intl';addLocaleDate([...en,...zh]);......render( , document.getElementById('container'));
需要传递两个参数:
locale是传递需要国际化的语言的缩写,通过这个参数可以确定格式化日期,数字,量词的时候按照哪一种语言的规则,这个是规则是intl提供的,一般浏览器会内置这个库,但是在Safari和IE11之前需要自己安装,安装的方法前面已经提及,请自己翻阅。
messages是用于传递刚刚我们在第3步中定义的配置文件的,从示例代码中我们可以看出,首先我们使用Import语句引入了配置文件,然后将配置文件的内容传递给了messages这个参数,此时组件中的所有组件都可以拿到配置文件中的内容了。
那个跳起来的同学,请先坐下,我猜你是想问,是不是每次都要手动修改这两个参数以适配不同语言呢?
其实不然,我们完全可以按照下面的做法自动识别当前浏览器的语言:
chooseLocale(){ switch(navigator.language.split('_')[0]){ case 'en': return 'en_US'; break; case 'zh': return 'zh_CN'; break; ... ... ... default: return 'en_US'; break; }}render( , document.getElementById('container'));
您还需要知道的是,是可以嵌套使用的,也就是说,在一个内部还可以有N个,这个功能的实际意义就是可以在英文网站中嵌套一个中文的或者德语的或者法语的板块,应用起来会更加灵活一些。
5. 使用
前面的几个步骤其实都是为了这个步骤做铺垫的,在添加了之后,我们就可以在其包裹的及包含的所有组件中获取到配置文件的信息,传入组件的id参数也能其在配置文件中对应的字符串了。
使用的方法如下:
在Js执行的时候,组件就会找到配置文件中,‘hello'键名对应的字符串'Hello, Howard!'.
输出的结果为:
Hello, Howard!
那么如何输出含有动态参数的字符串呢?比如Hello,Johnson!,如果我要问候的对象是一个变量呢?
那就这么写呗。。
以上的例子中,赋给someone的就是一个变量(假设这个变量是通过参数传进这个组件的),注意,如果是这样的话,那么locale配置文件中就要这么写。
superHello:"你好,{ someone } !"
前面其实提过了,怕你忘了...我已经悄无声息的把id换成了superHello。
更牛逼的是,这个someone还可以包含HTML标签!
this.props.name, } />
输出结果:
Hello, Howard!
于是,这个名字就被加粗了。
眼尖的同学又要跳起来了,“webFunc,为什么所有的输出都带一个标签,我就不能换成别的么?”
不要着急,我正要说这个,对于这个问题,官方的文档是这么说的。
By default will render the formatted string into
a . If you need to customize rendering, you can either wrap it
with another React element (recommended), specify a different tagName
(e.g., 'div'), or pass a function as the child.
翻译过来就是,默认的是会包裹在标签中的,如果想要让输出的字符串包裹在其他标签中的话,比如你想包裹在中,你就把组件包含在一对中间,这是一种官方更加推荐的做法。
Well, that's stupid...
或者你可以给传入一个tagName的参数。比如:
就会输出:
Hello, Howard!
比较奇葩的是,也是我揣测作者不推荐使用这种方法的原因是...只要你高兴,tagName可以传入任意字符串,比如 shit:
就会输出:
Hello, Howard!
Yes, shit happens.
看到这里,你应该已经会使用React-intl对你的项目进行语言国际化了,没有进一步描述的地方,请自行查阅官方文档(项目地址:https://github.com/yahoo/react-intl),或者给我留言,虽然我不一定会及时回复。
--写在后面:
语言国际化应该是一个比较经常遇到的需求,但是我在完成项目的过程中,看到的中文的资料却相当少,虽然这不是一篇非常牛叉的技术文章,但是可能会帮到很多人,如若如此,也便满足了。
——方浩(webFunc)
对了,你可以关注一下我的微信公众号:webcoding
关键字:JavaScript, react.js
版权声明
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!