前端使用react-intl-universal进行国际化

一、国际化 / i18n

目前国际化,就是开发者写对象,一个key关联若干语种的翻译。相比于浏览器自带的翻译功能,语义更加准确。

“国际化”的简称:i18n(其来源是英文单词 internationalization的首末字符i和n,18为中间的字符数)

二、react项目国际化

react-intl是业界最受欢迎的软件包之一:React-intl是雅虎的语言国际化开源项目FormatJS的一部分,通过其提供的组件和API可以与ReactJS绑定。这种方法引入了两个主要问题:
一:只能应用于视图层,例如React.Component。对于Vanilla JS文件(原生JS),无法对其进行国际化。
二:要获取React.Component的实例,react-intl不能使用常规方法如this.refs.comname

相比之下,react-intl-universal具有以下特征:

  • react-intl-universal不仅可以在React.Component中使用,还可以在Vanilla JS中使用
  • 简单。只有三个主要的API和一个可选的帮助器。
  • 显示不同语言环境的数字,货币,日期和时间。
  • 多元化字符串中的标签。
  • 消息中的支持变量。
  • 在消息中支持HTML。
  • 支持150多种语言。
  • 在浏览器和Node.js中运行。
  • 消息格式由ICU标准严格执行。
  • 支持嵌套JSON格式的语言环境数据。

三、具体实现

1. 安装

cnpm install react-intl-universal --save

2. App.js文件

本地语言文件

在这里插入图片描述
en-US.json

{"tableTitle": "Results","searchBoardTitle": "filter","ReportNumber": "Report Number"
}

zh-CN.json

{"tableTitle": "列表","searchBoardTitle":"查询","ReportNumber": "报案号"
}

引入ant组件、加载语言环境数据

import { ConfigProvider } from 'antd';
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';
const locales = {'en-US': require('./locales/en-US.json'),'zh-CN': require('./locales/zh-CN.json'),
};
...

初始化语言

class App extends React.PureComponent {constructor(props) {super(props);this.state = {antdLang: zh_CN,  // 修改antd  组件的国际化}}async componentWillMount(){const { userStore, history } = this.props;emit.on('change_language', lang => this.loadLocales(lang)); // 监听语言改变事件this.loadLocales(); // 初始化语言}loadLocales(lang = 'en-US') {intl.init({currentLocale: lang,  // 设置初始语言locales,}).then(() => {this.setState({antdLang: lang === 'zh-CN' ? zh_CN : en_US});});}
...

加入antd的LocaleProvider 组件:该组件接受一个属性 locale,该属性为当前语言的文案。antd 会通过 react 的 context 将这些信息传递给被 LocaleProvider 包裹的子组件,

  render() {return (<ConfigProvider locale={this.state.antdLang}> <div className={styles.App}><PolestarApp><Header /><Suspense fallback={<div></div>}><Switch><Route path='/' exact component={Home} /></Switch></Suspense></PolestarApp></div></ConfigProvider>)}

3. emit.js文件

通过events实现事件监听,即在header切换语言时(发送消息),把切换事件传递到App.js中(接收消息)

const EventEmitter = require('events').EventEmitter; 
const emit = new EventEmitter(); 
export { emit };

4. header中增加语言切换

import React from 'react';
import styles from './header.module.css';
import { Select } from 'antd';
import { emit } from '../../emit.js'function Header() {const handleChange =(val) => {// 发送消息emit.emit('change_language', val);}return (<div className={styles.header_container}><p className={styles.header_name}></p><Select defaultValue="English" onChange={handleChange}><Option value="en-US">English</Option><Option value="zh-CN">中文</Option></Select></div>)
}export default Header;

5.国际化

1. 业务组件的国际化

以claimsManage.js为例:

import intl from 'react-intl-universal'; // 引入

原先写死的部分改成intl.get(key)
在这里插入图片描述

2.单独抽取出的js文件的国际化

在这里插入图片描述
如果直接在js文件中引入react-intl-universal并使用intl.get(label),传递给searchBoard组件的label为空,需要将原先导出对象,改写成一个function,这样就可以在locales的国际化初始化完成的后,再生成新的配置对象,改写后内容如下:

import intl from 'react-intl-universal';const SearchFormSetting =  () => ({lineNum: 4,data: [{type: 'TextField',initialValue: '',label: intl.get('ReportNumber'),key: 'claimId',},{type: 'DatePickerField',initialValue: '',label: intl.get('ReportStartTime'),longLabel: true,key: 'reportStartTime'},{type: 'DatePickerField',initialValue: '',longLabel: true,label: intl.get('ReportEndTime'),key: 'reportEndTime'},]} 
)
export default SearchFormSetting

3.其他

1)带变量的消息

get方法的第二个参数中的变量name、where将会被替换成字符串

组件:

<p>{intl.get('HELLO', { name: 'Tony',where:intl.get('where') }) }</p>

en-US.json

 "where": "Hangzhou",
"HELLO": "Hello {name},welcome to {where}!" 

zh-CN.json

"where": "杭州","HELLO": "你好 {name},欢迎来到{where}!"

在这里插入图片描述
在这里插入图片描述

2)数字:复数形式和千分符

组件:

<p>{intl.get('CHANCE', { num: 0 })}</p>
<p>{intl.get('CHANCE', { num: 1 })}</p>
<p>{intl.get('CHANCE', { num: 10000000 })}</p>

en-US.json

"CHANCE": "rest chances:{num, plural, =0 {none.} =1 {one chance.} other {# chances.}}"

zh-CN.json

"CHANCE": "剩余次数为{num, plural, =0 {零。} =1 {1次。} other {# 次.}}"

在这里插入图片描述
在这里插入图片描述

3)显示货币

语言环境数据采用ICU格式。
语法为{名称,类型,格式}。
在如下示例中:
price是消息中的变量名称
类型有number,date,和time。
format是可选的,如果format是货币代码之一,它将以相应的货币格式显示。
如果type为number和format省略,则结果为带千分符的格式化数字。

组件:

{intl.get('SALE_PRICE', { price: 123456.78 })}

en-US.json

"SALE_PRICE": "The price is {price, number, USD}"

zh-CN.json

"SALE_PRICE": "价格是 {price, number, CNY}"

在这里插入图片描述

在这里插入图片描述
货币代码对照表
在这里插入图片描述

4)显示日期

type为date,则format具short、medium、long、full四个值,不同type对日期描述的详尽程度也不同,不穿默认为short

组件:

{intl.get('SALE_START', { start: new Date() })}
{intl.get('SALE_END', { end: new Date() })}

en-US.json

"SALE_START": "Sale begins from {start, date}",
"SALE_END": " to {end, date, long}"

zh-CN.json

"SALE_START": "活动从{start, date}开始,",
"SALE_END": "{end, date, long}结束"
type - short

在这里插入图片描述
在这里插入图片描述

type - meduim(英:月份简写)

在这里插入图片描述

在这里插入图片描述

type - long(英:月份全称)

在这里插入图片描述
在这里插入图片描述

type - full(具体到星期)

在这里插入图片描述

在这里插入图片描述

5)设置默认值

组件:

class Locale extends React.Component {render() {const name = 'Tony';return (<div>{intl.get('HELLO', { name }).defaultMessage(`Hello, ${name}`)}</div>);}
}

en-US.json

 "HELLO": "Hello, {name}" 

zh-CN.json

"HELLO": "你好, {name}"

在这里插入图片描述在这里插入图片描述

6)返回HTML

组件:

{intl.getHTML('TIP')}

en-US.json

"TIP": "This is <span style='color:red'>SPAN</span>" 

zh-CN.json

"TIP": "<span style='color:red'>span元素</span>" 

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/251261.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

守护线程Daemon的理解

1、守护线程伴随着主线程的销毁而销毁&#xff1b; 2、jvm虚拟机中有很多守护线程&#xff0c;随着main函数的结束而结束&#xff0c;自动回收栈中的内容。 Thread t1 new Thread(){Overridepublic void run() {for (int i 0; i < 10; i) {try {Thread.sleep(1000);} catc…

javascript --- 异步函数的顺序进行

假设我们希望某一组异步函数能一次进行,在不使用的任何工具的情况下,可能会编写出类似下面的代码: funcs[0](function() {funcs[1](function() {funcs[2](onComplete);}) });// 注:以上代码运行会出现的一些不方便: // 1.回调太深,不利于阅读..(100层嵌套...); // 2.不能使用循…

2021前端面试题

基础知识与素养 JS基本功训练与思考 程序设计的渗透与应用 业务技巧的积累与训练 生产力转换 项目的组织架构 转换专业人才的全面生产力 什么样的技术水平决定了你应该学习什么样的知识与技术&#xff0c;什么样的知识与技术水平决定了你到什么样的公司&#xff0c;到什么样的公…

JS的自定义事件(观察者模式)

1      var Event {2 on: function (eventName, callback) {3 console.log("eventName:"eventName)4 if (!this.handles) {5 Object.defineProperty(this, "handles", {6 …

glog日志库使用笔记

日志能方便地诊断程序原因、统计程序运行数据&#xff0c;是大型软件系统必不可少的组件之一。glog 是google的开源日志系统&#xff0c;相比较log4系列的日志系统&#xff0c;它更加轻巧灵活。 在Github上下载glog&#xff0c;解压后用CMake生成VS2017工程&#xff08;默认生成…

javascript --- 异步工作流的动态排队技术

很多情况下,使用async.series和async.paralle存在一个明显的问题,即: 1.其任务队列是静态的,在其调用前,一定要明确任务队列的数量,一旦明确了任务队列的数量,就不能改变. 2.倘如要同时并发读取上千个文件,使用async.paralle明显不可能(各线程抢资源,根本不够用),使用async.ser…

java中的内部类总结

内部类不是很好理解&#xff0c;但说白了其实也就是一个类中还包含着另外一个类 如同一个人是由大脑、肢体、器官等身体结果组成&#xff0c;而内部类相当于其中的某个器官之一&#xff0c;例如心脏&#xff1a;它也有自己的属性和行为&#xff08;血液、跳动&#xff09; 显然…

elementPlus关闭弹窗,页面原先滚动条消失

一开始以为是弹窗内容超过一屏引起&#xff0c;改为一屏内也不能解决。 打开控制台&#xff0c;发现弹窗后自动给body标签加上了类el-popup-parent–hidden&#xff0c;关闭后也没去除&#xff0c;因此手动删除该类。 document.getElementsByTagName(body)[0].className ;

在Windows下如何创建虚拟环境(默认情况下)

很多小伙伴平时在使用Python的时候&#xff0c;有的项目需要使用Python2来进行开发&#xff0c;有的项目则是需要Python3来进行开发。当不清楚怎么分开环境的时候&#xff0c;此时两个环境开始打架&#xff0c;彼此傻傻分不清楚。虚拟环境作为隔离的利器应运而生&#xff0c;其…

javascript --- 隐藏内部实现(最小暴露原则)

看下面的一个例子: function doSomething(a) {b a doSomethingElse( a * 2 );console.log( b * 3 ); }function doSomethingElse(a) {return a - 1; }var b;doSomething( 2 ) ; // 15上述代码中的doSomethingElse实际上应该是doSomething的"私有"部分,根据最小暴露…

selenium python 入门-元素定位

环境搭建 安装教程 http://www.testclass.net/selenium_python/install-selenium/ chrome浏览器 还需要下载chrome driver 把下载的chromedriver .exe放到chrome安装目录下的Application目录下和 python所在的安装目录下&#xff0c;比如我的目录是C:\Program Files (x86)\Goog…

ES5程序设计转ES6 笔记

课程链接 1. 立即执行函数 特点&#xff1a;执行结束&#xff0c;立即销毁&#xff1b;独立作用域执行符号&#xff08;&#xff09;只能跟在表达式后面&#xff0c;不能放在函数声明后分号可以写在前面/后面document为传入实参&#xff0c;doc为形参 ;(function(doc){...co…

DPDK helloworld 源码阅读

在 DPDK Programmers Guides 中的 EAL 一篇中有一个图可以很清晰地看到一个DPDK的应用程序的大致执行思路&#xff1a; 初始化检查CPU支持、微架构配置等完成后&#xff0c;执行main()函数。 第一步是 rte_eal_init()&#xff0c;核心初始化和启动。其中线程使用的是pthread库&…

javascript --- 作用域和闭包

执行环境: // 定义了变量或函数有权访问的其他数据,决定了它们各自的行为 // 每个执行环境都有一个变量对象与之对应,执行环境中所定义的所有变量和函数都保存在变量对象中 // 某个执行环境中的所有代码执行完毕后,该执行环境被销毁,保存在其中的所有变量和函数定义也随之销毁…

异步下载圆形进度条显示进度

圆形进度条参考链接即可&#xff1a;使用css3实现圆形进度条 需求点击下载后遮罩层显示下载进度&#xff1a; 1.圆形进度条参考以上链接&#xff0c;有点小瑕疵&#xff0c;可更改定位距离实现重合。 2.遮罩层&#xff1a; .lbOverlay{display: none;position: fixed;left: 0;…

javascript基本功

隐式类型转换 var a {_default: 0,toString: function () {return a._default} } if (a 1 && a 2 && a 3) {console.log(解) } 访问一个变量的时候进行拦截 var _default 0 Object.defineProperty(window, a, {get() {return _default} }) if (a 1 &am…

深信服笔试,抓兔子

*问题描述&#xff1a;抓兔子n个排成一排的洞&#xff0c;编号为1到n&#xff0c;兔子每天晚上会跳到相邻的一个洞里&#xff0c;小q每天只能白天检查其中的一个洞&#xff0c;小q会告诉你每天检查的洞&#xff0c;分析是否一定能抓到兔子示例&#xff1a;3个洞&#xff0c;第一…

es6 --- 模块

function foo(){var something cool;var another [1, 2, 3];function doSomething() {console.log( something );}function doAnother() {console.log( another.join( " ! " ) );} } // 是一个不明显的闭包,doSomething()和doAnother()保持了foo的内部作用域接下来…

Java之递归遍历目录,修改指定文件的指定内容

EditProperties.java 1 package PropertiesOperation.Edit;2 3 import java.io.File;4 5 /**6 * 替换指定Porpoerties文件中的指定内容7 * 三个参数&#xff1a;8 * filePath&#xff1a;存放properties文件的目录9 * srcStr&#xff1a;需要替换的字符串 10 * desStr&…

学习日志---7

1.复习Linux hadoop hdfs MapReduce基础知识 1&#xff0c;列举linux常用命令 shutdown now reboot mkdir mkdir -p touch filename rm -r filename rm -rf filename vi filename i--->可编辑状态 esc --> : --->wq 保存退出 q! wq! cat grep find ifconfig ping user…