7月底开始,公的要把之前的一个项目增加国际化的需求。现在基本做完了,在转测阶段,就把之前的东西记录一下。
效果图
react-intl-universal包
由于项目是react的,所以使用的是react-intl-universal。其实这个npm包的使用还是很简单方便的。
具体实现
看过我之前的文章的同学,估计知道我之前的页面结构和代码。在国际化之前我适当的修改了一下。但是展示的结构不变。实际效果最上面的gif图有展示了。
- 引入react-intl-universal,这个看文档即可;
- 增加两个json文件;
- en-US.json 用于存放英文对应的数据
{ "key1": "Internationalization" }
- zh-CN.json 用于存放中文对应的数据
{ "key1": "国际化" }
intl.get(key)
这里用到的key 就是这两个json文件中的key值。 - en-US.json 用于存放英文对应的数据
- 新增一个
locale.js
的页面文件; - 修改App.js文件,代码如下:
import React, { Component } from 'react';
import { BrowserRouter as Router} from 'react-router-dom';
import MyRoute from './router.js';
import {emit} from './emit.js'
import zh_CN from 'antd/es/locale/zh_CN';
import en_US from 'antd/es/locale/en_US';
import intl from 'react-intl-universal';
import { ConfigProvider } from 'antd';
import './App.css';
import './index.less';
const locales = {
'en-US': require('./locales/en-US.json'),
'zh-CN': require('./locales/zh-CN.json'),
};
class App extends Component {
constructor(props) {
super(props);
this.state = {
antdLang: zh_CN, // 修改antd 组件的国际化
}
}
componentDidMount() {
emit.on('change_language', lang => this.loadLocales(lang)); // 监听语言改变事件
this.loadLocales(); // 初始化语言
}
loadLocales(lang = 'zh-CN') {
intl.init({
currentLocale: lang, // 设置初始语音
locales,
}).then(() => {
this.setState({
antdLang: lang === 'zh-CN' ? zh_CN : en_US
});
});
}
render() {
return (
// ConfigProvider antd 组件的国际化
<ConfigProvider locale={this.state.antdLang}>
<Router>
<MyRoute />
</Router>
</ConfigProvider>
);
}
}
export default App;
这里有几点需要注意的:
-
antd 的国际化:https://ant-design.gitee.io/docs/react/i18n-cn 这里需要看这个文档
我使用的antd 是 3.16.2版本,所以使用的是ConfigProvider
组件用于antd组件的全局国际化,有的版本使用的是LocaleProvider
,两个组件用法一样,大家根据自己的版本选择。 -
事件监听,这里是通过
events
实现的,就是导航栏在改变语言时,把改变事件传递到App.js中;传递到其他文件也可以的,只需要增加对应的监听时间即可 -
事件监听的实现:
- emit.js 文件:
const EventEmitter = require('events').EventEmitter; const emit = new EventEmitter(); export { emit };
- 发送消息
发送消息是在Header
组件中做的,Header.js
文件内容
import React, { Component } from 'react'; import { Select } from 'antd'; import {emit} from '../../emit.js' import '../../assets/css/index.less' const { Option } = Select; class Header extends Component { handleChange(val) { // 发送消息 emit.emit('change_language', val); } render() { return ( <div className='header'> Header <Select defaultValue="中文" onChange={this.handleChange.bind(this)}> <Option value="zh-CN">中文</Option> <Option value="en-US">English</Option> </Select> </div> ); } componentDidMount() { } } export default Header;
- 接收消息
这个在App.js
文件中,这里不多说了。
-
页面国际化的实现
import React from 'react';
import intl from 'react-intl-universal';
class Locale extends React.Component {
render() {
return (
<div className='locale'>
<p>国际化测试: {intl.get('key1')}</p>
</div>
);
}
componentDidMount() {
}
}
export default Locale;
到这里一个简单的国家化demo基本完成。
小结
其实国际化的实现不难。但是在项目中有很多细节需要处理,比如: antd 组件的国际化,antd 日历组件的处理,下拉组件的处理。在做的时候,要注意antd 提供的国际化组件,也要注意react-intl-universal的使用。很多细节,坑,需要大家自己踩了自己才会知道。项目代码下载地址:https://gitee.com/hgdq/myblog.git