前端使用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.pswp.cn/news/251261.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/251261.shtml
英文地址,請注明出處:http://en.pswp.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…