前言

之前写过一篇关于React的国际化文章,主要是用react-intl库,雅虎开源的。react-intl是用高阶组件包装一层来做国际化。

基于组件化会有一些问题,比如在一些工具方法中需要国际化,就需要自己去实现了。在umi-react快速开发框架我们采用

react-intl-universal库来实现,不仅支持组件化调用,也支持动态调用,实现国际化。

react-intl-universal 用法

  1. 安装
```
npm install react-intl-universal --save
```
  1. 初始化

    在以下示例中,我们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>
    );
    } }
  2. 调用

    • 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项目中加入国际化

  1. 在根目录新建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: '退出登录'
}
}
```
  1. 在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,
    };
    },
    },
    };
  2. 在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;
  3. 在 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;
  4. 到此我们的系统国际化就可以用了。我们把登陆页面国际化完善起来。这要调用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快速开发框架(国际化)的更多相关文章

  1. 01 基于umi搭建React快速开发框架

    介绍 基于umi搭建一个快速开发框架,react 应用框架.umi 以路由为基础的,支持类 next.js 的约定式路由,以及各种进阶的路由功能,并以此进行功能扩展,比如支持路由级的按需加载. 我们会 ...

  2. 03 基于umi搭建React快速开发框架(封装列表增删改查)

    前言 大家在做业务系统的时候,很多地方都是列表增删改查,做这些功能占据了大家很长时间,如果我们有类似的业务,半个小时就能做出一套那是不是很爽呢. 这样我们就可以有更多的时间学习一些新的东西.我们这套框 ...

  3. ABP开发框架前后端开发系列---(14)基于Winform的ABP快速开发框架

    前面介绍了很多ABP系列的文章,一步一步的把我们日常开发中涉及到的Web API服务构建.登录日志和操作审计日志.字典管理模块.省份城市的信息维护.权限管理模块中的组织机构.用户.角色.权限.菜单等内 ...

  4. Mario是一个基于.NETCore的简单快速开发框架

    Mario .NET Core简单快速开发框架 Mario是一个基于.NET Core的简单快速开发框架 GitHub:https://github.com/deeround/Mario 技术特点 基 ...

  5. SpringCloud微服务实战——搭建企业级开发框架(四十六):【移动开发】整合uni-app搭建移动端快速开发框架-环境搭建

      近年来uni-app发展势头迅猛,只要会vue.js,就可以开发一套代码,发布移动应用到iOS.Android.Web(响应式).以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/ ...

  6. 【玩转 WordPress】基于 Serverless 搭建个人博客图文教程,学生党首选!

    以下内容来自「玩转腾讯云」用户原创文章,已获得授权. 01. 什么是 Serverless? 1. Serverless 官方定义 Serverless 中的 Server是服务器的意思,less 是 ...

  7. 基于SpringBoot+Mybatis+AntDesign快速开发平台,Jeecg-Boot 1.1 版本发布

    Jeecg-Boot 1.1 版本发布,初成长稳定版本 导读     平台首页UI升级,精美的首页支持多模式 提供4套代码生成器模板(支持单表.一对多) 集成Excel简易工具类,支持单表.一对多导入 ...

  8. Known快速开发框架

    Known是一个基于.NET开发的快速开发框架,前后端分离,使用极少的第三方组件,开发简单快速,大部分代码可通过代码生成工具自动生成,非常适合单兵作战和小团队开发.前端UI是一个基于JQuery开发的 ...

  9. Reactjs-generator-cli 一款基于Ink构建用于快速搭建React应用的CLI scaffolding工具

    Reactjs-generator-cli 一款基于Ink构建用于快速搭建React应用的CLI scaffolding工具 A simple CLI for scaffolding React.js ...

随机推荐

  1. 六大主流开源SQL引擎

    导读 本文涵盖了6个开源领导者:Hive.Impala.Spark SQL.Drill.HAWQ 以及Presto,还加上Calcite.Kylin.Phoenix.Tajo 和Trafodion.以 ...

  2. PAT A1132 Cut Integer (20 分)——数学题

    Cutting an integer means to cut a K digits lone integer Z into two integers of (K/2) digits long int ...

  3. https安全协议原理

    那么什么是HTTPS? HTTPS(Hypertext Transfer Protocol Secure)是一种通过计算机网络进行安全通信的传输协议.HTTPS经由HTTP进行通信,但利用TLS来加密 ...

  4. Luogu P2700 逐个击破

    qwq 同关押罪犯 对于这种希望几个对象分开的题目,只要把并查集反过来想就可以了. 既然要求删除的边权最小,那么只要反过来求给定的点不连通时保留的边权最大即为正解. 同样的,首先将边权排序,不会使敌人 ...

  5. docker镜像的创建commit及dockerfile

    在docker 1.3版本以前使用attach进入容器会经常出现卡死的情况,之后官方退出了exec命令,从宿主机进入,但是从其他远程主机进入使用ssh服务来维护是用户熟悉的方法.所以这里来创建一个带有 ...

  6. 9-(基础入门篇)云端安装MQTT服务器

    https://www.cnblogs.com/yangfengwu/p/9953703.html 记得把文件拷贝到上一节配置的和云端共享的那个盘里面,好拷贝文件到云服务器 进入到bin目录 咱先以控 ...

  7. React-本地状态(state)

    在类组件中添加本地状态(state): 1.创建一个继承自 React.Component 类的 ES6 class 同名类: 2.添加一个 类构造函数(class constructor) 初始化 ...

  8. 【JVM.2】垃圾收集器与内存分配策略

    垃圾收集器需要完成的3件事情: 哪些内存需要回收? 什么时候回收? 如何回收? 在前一节中介绍了java内存运行时区域的各个部分,其中程序计数器.虚拟机栈.本地方法栈3个区域随线程而生,随线程而灭:栈 ...

  9. 程序员从技术开发到项目管理PM--思维转变

    对以往所做项目的经验做下总结,作为项目经理首先要对项目负责,思维要做下转变,要从项目全局角度考虑问题:     从个人成就到团队成就. 无论是做管理还是做技术,成就导向意识是优秀员工的基本素质.只有具 ...

  10. 挂载银行前置机Ukey到windows server2012虚拟机的操作记录

    公司有跟银行对接的金融业务,需要配置银行前置机环境.通过KVM的WebVirtMgr管理平台创建windows server2008虚拟机,安装参考:kvm虚拟化管理平台WebVirtMgr部署-完整 ...