02 基于umi搭建React快速开发框架(国际化)
前言
之前写过一篇关于React的国际化文章,主要是用react-intl库,雅虎开源的。react-intl是用高阶组件包装一层来做国际化。
基于组件化会有一些问题,比如在一些工具方法中需要国际化,就需要自己去实现了。在umi-react快速开发框架我们采用
react-intl-universal库来实现,不仅支持组件化调用,也支持动态调用,实现国际化。
react-intl-universal 用法
- 安装
```
npm install react-intl-universal --save
```
初始化
在以下示例中,我们intl使用app locale data(locales)初始化并确定动态使用哪个区域设置(currentLocale).
然后intl.get(...)用来获取国际化的消息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>
);
} }
调用
HTML Message (HTML 消息)
locale data:
{ "TIP": "This is <span style='color:red'>HTML</span>" }
js code:
intl.getHTML('TIP');
Default Message (设置默认消息)
js code:intl.get('not-exist-key').defaultMessage('default message')
也可以用简写设置默认值
intl.get('not-exist-key').d('default message')
getHTML 也支持默认值
intl.getHTML('not-exist-key').d(<div>hello</div>)
Message With Variables (消息添加变量)
locale data:
{ "HELLO": "Hello, {name}. Welcome to {where}!" }
js code:
intl.get('HELLO', {name:'Tony', where:'Alibaba'})
在umi-react项目中加入国际化
在根目录新建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
02 基于umi搭建React快速开发框架(国际化)的更多相关文章
- 01 基于umi搭建React快速开发框架
介绍 基于umi搭建一个快速开发框架,react 应用框架.umi 以路由为基础的,支持类 next.js 的约定式路由,以及各种进阶的路由功能,并以此进行功能扩展,比如支持路由级的按需加载. 我们会 ...
- 03 基于umi搭建React快速开发框架(封装列表增删改查)
前言 大家在做业务系统的时候,很多地方都是列表增删改查,做这些功能占据了大家很长时间,如果我们有类似的业务,半个小时就能做出一套那是不是很爽呢. 这样我们就可以有更多的时间学习一些新的东西.我们这套框 ...
- ABP开发框架前后端开发系列---(14)基于Winform的ABP快速开发框架
前面介绍了很多ABP系列的文章,一步一步的把我们日常开发中涉及到的Web API服务构建.登录日志和操作审计日志.字典管理模块.省份城市的信息维护.权限管理模块中的组织机构.用户.角色.权限.菜单等内 ...
- Mario是一个基于.NETCore的简单快速开发框架
Mario .NET Core简单快速开发框架 Mario是一个基于.NET Core的简单快速开发框架 GitHub:https://github.com/deeround/Mario 技术特点 基 ...
- SpringCloud微服务实战——搭建企业级开发框架(四十六):【移动开发】整合uni-app搭建移动端快速开发框架-环境搭建
近年来uni-app发展势头迅猛,只要会vue.js,就可以开发一套代码,发布移动应用到iOS.Android.Web(响应式).以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/ ...
- 【玩转 WordPress】基于 Serverless 搭建个人博客图文教程,学生党首选!
以下内容来自「玩转腾讯云」用户原创文章,已获得授权. 01. 什么是 Serverless? 1. Serverless 官方定义 Serverless 中的 Server是服务器的意思,less 是 ...
- 基于SpringBoot+Mybatis+AntDesign快速开发平台,Jeecg-Boot 1.1 版本发布
Jeecg-Boot 1.1 版本发布,初成长稳定版本 导读 平台首页UI升级,精美的首页支持多模式 提供4套代码生成器模板(支持单表.一对多) 集成Excel简易工具类,支持单表.一对多导入 ...
- Known快速开发框架
Known是一个基于.NET开发的快速开发框架,前后端分离,使用极少的第三方组件,开发简单快速,大部分代码可通过代码生成工具自动生成,非常适合单兵作战和小团队开发.前端UI是一个基于JQuery开发的 ...
- Reactjs-generator-cli 一款基于Ink构建用于快速搭建React应用的CLI scaffolding工具
Reactjs-generator-cli 一款基于Ink构建用于快速搭建React应用的CLI scaffolding工具 A simple CLI for scaffolding React.js ...
随机推荐
- Qt warning: 构建目录必须和源文件目录为同级目录
从一台电脑转移项目到另一电脑, 路径发生变化,重新构建运行时会出现“QT 构建目录必须和源目录为同级目录”提示,解决办法很加单.如下: 方法一: 点击 project(项目)->然后,看看Bui ...
- VMware虚拟机将英文改成中文的方法
由于之前安装的虚拟机和老师要求的不同,我安装的是VMware,所以没有安装教程,没能修改系统语言,用了几次发现英文的不太方便,特别是出错的时候,看不懂系统的出错提示. 我从网上参考了https://b ...
- python链家网高并发异步爬虫asyncio+aiohttp+aiomysql异步存入数据
python链家网二手房异步IO爬虫,使用asyncio.aiohttp和aiomysql 很多小伙伴初学python时都会学习到爬虫,刚入门时会使用requests.urllib这些同步的库进行单线 ...
- 【Codeforces Round 464】Codeforces #265 (Div. 1)
模拟RD265 ABC三题,Rank58 Codeforces 464 A 题意:给定一个字符串,求比这个字符串字典序大并且和它长度相等的第一个不含有长度大于等于2的回文串的字符串. 思路:首先我们枚 ...
- http协议进阶(六)代理
web代理服务器是网络的中间实体,位于客户端和服务器之间,扮演“中间人”的角色,作用是在各端点之间来回传送报文. 其原理是:客户端向代理服务器发送请求报文,代理服务器正确的处理请求和连接,然后返回响应 ...
- 2-关于单片机通信数据传输(中断接收,大小端,IEEE754浮点型格式,共用体,空闲中断,环形队列)
上一篇链接 http://www.cnblogs.com/yangfengwu/p/8628219.html 先说明一点这种方式,不光对于单片机类的,,对于上位机接收数据同样适用----不骗人的,自己 ...
- ORA-14551: 无法在查询中执行 DML 操作
编写了一个oracle函数,函数体内实现一系列数据库的逻辑处理,涉及到数据的增删等操作,返回NCLOB类型. 然后通过查询方式调用函数: SELECT PKG.MY_FUN('A') FROM DUA ...
- electron 开发实时加载
第一个方式 cnpm install electron-reload --save-dev cnpm install electron-prebuilt --save-dev require('ele ...
- 没有 iOS 开发者账号的情况下部署到真机的方法
原文发表于我的技术博客 本文分享了官方推荐的没有 iOS 开发者账号的情况下部署到真机的方法,供参考. 原文发表于我的技术博客 1. 官方推荐的方法 原文在此,也就是 Ionic 官方团队在博客中分享 ...
- 完整部署CentOS7.2+OpenStack+kvm 云平台环境(2)--云硬盘等后续配置
继上一篇博客介绍了完整部署CentOS7.2+OpenStack+kvm 云平台环境(1)--基础环境搭建,本篇继续讲述后续部分的内容 1 虚拟机相关1.1 虚拟机位置介绍 openstack上创建的 ...