最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 国际化方案,从umi2.x升级到umi3.x

    正文概述 掘金(Atomospher)   2021-02-06   1264

    1. 引论

    目前umi已经发布到3.x的版本,项目升级后,发现以前的国际化方案不是很适用于目前大量使用hook的react项目。现在直接从umi/locale中使用formatMessage,umi会在控制台告警:

    2. locales升级

    umi3.x的国际化方案是基于插件``@umijs/plugin-locale, 在umi内部自身携带有这个插件,想要使用它,需要在.umirc.js`文件中进行如下配置:

      locale: {
        default: 'zh-CN',
        antd: false,
        title: false,
        baseNavigator: true,
        baseSeparator: '-',
      }
    

    接着,需要在src目录下创建locales文件夹,并创建相应语言的 js 或 ts 文件, 如en-US.js,umi会根据当前的locales去读取相应文件里的信息。

    export default {
      'navBar.lang': 'Languages: {language}',
      'layout.user.link.help': 'Help',
      'layout.user.link.privacy': 'Privacy',
      'layout.user.link.terms': 'Terms',
      'app.preview.down.block': 'Download this page to your local project',
      'app.welcome.link.fetch-blocks': 'Get all block',
      'app.welcome.link.block-list': 'Quickly build standard, pages based on `block` development',
    };
    

    3. 在class component中使用国际化

    在类组件中,我们需要使用injectIntlinjectIntl是一个HOC,使用它可为ReactComponent注入intl对象,通过this.props.``intl使用它。

    import React, {Component} from 'react'
    import {injectIntl} from 'react-intl'
    
    interface Props {
      date: Date | number
    }
    
    class DemoComponent extends Component {
     render() {
       const { intl } = this.props;
       return (
         <div>
         {intl.formatMessage(
            {
              id: 'navBar.lang',
            },
            {
              language: 'English',
            }
          )}<div>
       )
    }
    
    export default injectIntl(FunctionalComponent)
    

    4. 在function component中使用国际化

    函数式组件中可以如class组件一样直接使用高阶函数injectIntl注入intl,也可以使用hook useIntl:

    import React from 'react'
    import {useIntl} from 'react-intl'
    
    const FunctionComponent: React.FC<{date: number | Date}> = ({date}) => {
      const intl = useIntl()
      return (
         <div>
         {intl.formatMessage(
            {
              id: 'navBar.lang',
            },
            {
              language: 'English',
            }
          )}<div>
       )
    }
    
    export default FunctionComponent
    

    5. 在非react组件中使用国际化

    以上两种无论是高阶函数或者hook是无法在普通的js、ts文件中使用的,为此我们需要createIntl来创建一个Intl实例。为了方便,我们可以统一封装一下:

    import { createIntl, createIntlCache, getLocale  } from 'umi';
    import enUS from 'locales/en-US';
    import zhCN from 'locales/zh-CN';
    
    class Locales {
      intl;
    
      // 需要将locales中的json数据手动注入到Intl实例中
      messages = {
        'zh-CN': zhCN,
        'en-US': enUS
      }
    
      /**
       * [instance  当前实例]
       * @type {this}
       */
      static instance
      /**
       * [getInstance 获取单例]
       * @method getInstance
       * @return {[type]}    [description]
       */
      static getInstance() {
        if (false === this.instance instanceof this) {
          this.instance = new this();
        }
        return this.instance;
      }
    
      constructor() {
        this.init();
      }
    
      init() {
        const locales = getLocale() || 'zh-CN';
        const cache = createIntlCache();
        const intl = createIntl({
          locale: locales,
          // 需要将locales中的json数据手动注入到Intl实例中
          messages: this.messages[locales]
        }, cache);
        this.intl = intl;
      }
    
      changeLocales() {
        const locales = getLocale() || 'zh-CN';
        const cache = createIntlCache();
        const intl = createIntl({
          locale: locales,
          messages: this.messages[locales]
        }, cache);
        this.intl = intl;
      }
    
      formatMessage = (id, values) => {
        if(values) {
          return this.intl.formatMessage(
            { id },
            {...values}
          )
        }
        return this.intl.formatMessage({ id })
      }
    
    }
    
    const Intl = Locales.getInstance();
    
    export  default Intl;
    
    

    在文件使用:

    import Intl from 'locales.js; // 从上面文件中引入
    
    const formatedMessage = Intl.formatMessage('navBar.lang');
    

    6. 切换语言

    可通过setLocale来进行当前语言的切换,设置切换语言,默认会刷新页面,可以通过设置第二个参数为 false ,来实现无刷新动态切换。

    import { setLocale } from 'umi';
    // 刷新页面
    setLocale('zh-TW', true);
    // 不刷新页面
    setLocale('zh-TW', false);
    

    7. 后言

    @umijs/plugin-locale 基于 react-intl 封装,支持其所有的 api,详情可以看 这里。 相关详细文档及api地址:


    起源地下载网 » 国际化方案,从umi2.x升级到umi3.x

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元