以前寫過一篇關於React的國際化文章,主要是用react-intl庫,雅虎開源的。react-intl是用高階組件包裝一層來作國際化。
基於組件化會有一些問題,好比在一些工具方法中須要國際化,就須要本身去實現了。在umi-react快速開發框架咱們採用
react-intl-universal庫來實現,不只支持組件化調用,也支持動態調用,實現國際化。html
npm install react-intl-universal --save
初始化
在如下示例中,咱們intl使用app locale data(locales)初始化並肯定動態使用哪一個區域設置(currentLocale).
而後intl.get(...)用來獲取國際化的消息react
import intl from 'react-intl-universal'; const locales = { "en-US": require('./locales/en-US.js'), "zh-CN": require('./locales/zh-CN.js'), }; class App extends Component { state = {initDone: false} componentDidMount() { this.loadLocales(); } loadLocales() { // init method will load CLDR locale data according to currentLocale // react-intl-universal is singleton, so you should init it only once in your app intl.init({ currentLocale: 'en-US', // TODO: determine locale here locales, }) .then(() => { // After loading CLDR locale data, start to render this.setState({initDone: true}); }); } render() { return ( this.state.initDone && <div> {intl.get('SIMPLE')} </div> ); } }
調用git
HTML Message (HTML 消息)github
locale data:npm
{ "TIP": "This is <span style='color:red'>HTML</span>" }
js code:antd
intl.getHTML('TIP');
Default Message (設置默認消息)
js code:app
intl.get('not-exist-key').defaultMessage('default message')
也能夠用簡寫設置默認值框架
intl.get('not-exist-key').d('default message')
getHTML 也支持默認值less
intl.getHTML('not-exist-key').d(<div>hello</div>)
Message With Variables (消息添加變量)ide
locale data:
{ "HELLO": "Hello, {name}. Welcome to {where}!" }
js code:
intl.get('HELLO', {name:'Tony', where:'Alibaba'})
在根目錄新建locales文件夾, 添加locale描述文件
en_US.js 文件
export default { user: { login: { loginBtn: 'login', placeholderName: 'Please input user name', placeholderPws: 'Please input password', forgetPwd: 'Forget password', remember: 'Remember me', }, logout: 'logout' } }
zh_CN.JS 文件
export default { user: { login: { loginBtn: '登陸', placeholderName: '請輸入用戶名', placeholderPws: '請輸入密碼', forgetPwd: '忘記密碼', remember: '記住我', }, logout: '退出登陸' } }
在global modle中添加初始化state和Effect(changeLocale)和reducers(setLocale)
import intl from 'react-intl-universal'; import locales from '../locales'; import storage from 'utils/localStorage'; const defaultState = { currLocale: storage.get('locale') || 'zh_CN', localeLoad: false, } export default { namespace: 'global', state: defaultState, effects: { *changeLocale({ payload }, { call, put }) { const params = { currentLocale: payload, locales }; // 初始化國際化 yield intl.init(params); yield put({ type: 'setLocale', payload: { currLocale: payload, localeLoad: true, } }); // 把當前國際化持久化到 localstorage 中 storage.add('locale', payload); }, }, reducers: { setLocale(state, { payload }) { return { ...state, ...payload, }; }, }, };
在layouts index.js 中掉用changeLocale初始化國際化和antd組件國際化
import React, { Component } from 'react' import BaseLayout from './baseLayout'; import { LocaleProvider } from 'antd'; import { connect } from 'dva'; import zh_CN from 'antd/lib/locale-provider/zh_CN'; import en_US from 'antd/lib/locale-provider/en_US'; import { init } from './init'; @connect(({global}) => { return { currLocale: global.currLocale, localeLoad: global.localeLoad, } }) class Index extends Component { constructor() { super(); init(); this.state = { initDone: false, } } componentDidMount() { const {dispatch, currLocale} = this.props; // 更改國際化 dispatch({ type: 'global/changeLocale', payload: currLocale, }); } /** * 初始intl國際化和antd組件國際化 */ renderBody = () => { const {location: {pathname}, children, currLocale, localeLoad } = this.props; if (pathname === '/login') { return localeLoad && <React.Fragment> {children} </React.Fragment>; } return ( localeLoad && (<LocaleProvider locale={ currLocale === 'zh_CN' ? zh_CN : en_US }> <BaseLayout {...this.props} /> </LocaleProvider>) ); } render() { return ( <React.Fragment> {this.renderBody()} </React.Fragment> ) } } export default Index;
在 src/baseLayout/header.js 添加更改國際化的 select
import React, { Component } from 'react'; import { Avatar, Dropdown, Menu, Icon, Select } from 'antd'; import { connect } from 'dva'; import intl from 'react-intl-universal'; import styles from './baseLayout.less'; const Option = Select.Option; @connect(({user}) => { return { user: user.user } }) class Header extends Component { /** * 切換語言 */ onLocaleChange = (value) => { this.props.dispatch({ type: 'global/changeLocale', payload: value, }) } render() { const {currLocale, user} = this.props; return ( <div className={styles.header}> <div className={styles.headerButton}> <Select defaultValue={currLocale} style={{ width: 100 }} onChange={this.onLocaleChange}> <Option value='zh_CN'>中文</Option> <Option value='en_US'>English</Option> </Select> </div> </div> ) } } export default Header;
到此咱們的系統國際化就能夠用了。咱們把登錄頁面國際化完善起來。這要調用intl.get
方法
import intl from 'react-intl-universal'; @connect(({user}) => ({ loginErr: user.loginErr, })) @Form.create() class Login extends React.Component { render() { const { loginErr, form:{ getFieldDecorator } } = this.props; const intlLogin = intl.get('user.login.loginBtn'); const intlUsername = intl.get('user.login.placeholderName'); const intlPwd = intl.get('user.login.placeholderPws'); const intlforgetPwd = intl.get('user.login.forgetPwd'); const intlRemember = intl.get('user.login.remember'); return ( <div className={styles.login}> { loginErr && <Alert style={{ marginBottom: '20px' }} message='用戶名密碼錯誤' type='error' showIcon />} <Form onSubmit={this.handleSubmit} className='login-form'> <FormItem> {getFieldDecorator('name', { rules: [ FormValid.require(intlUsername), ], })( <Input prefix={<Icon type='user' style={{ color: 'rgba(0,0,0,.25)' }} />} placeholder={intlUsername} /> )} </FormItem> <FormItem> {getFieldDecorator('password', { rules: [ FormValid.require(intlPwd), ], })( <Input prefix={<Icon type='lock' style={{ color: 'rgba(0,0,0,.25)' }} />} type='password' placeholder={intlPwd} /> )} </FormItem> <FormItem> {getFieldDecorator('remember', { valuePropName: 'checked', initialValue: true, })( <Checkbox>{intlRemember}</Checkbox> )} <a className='login-form-forgot' href=''>{intlforgetPwd}</a> <Button type='primary' htmlType='submit' className='login-form-button'> {intlLogin} </Button> </FormItem> </Form> </div> ); } } export default Login;
國際化已經完成, 代碼已放到github上,你們能夠自行查看umi-react。若是以爲不錯,請 start 一下
我建了一個QQ羣,你們加進來,能夠一塊兒交流。羣號 787846148