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