Share This Post

簡介

如果一個應用程式在設計時,可以在不修改應用程式的情況下,根據不同的使用者直接採用不同的語言、數字格式、日期格式等,這樣的設計考量稱為國際化(internationalization),簡稱i18n(因為internationalization有18個字母)。

國際化的重要觀念之一是地區(Locale)資訊,地區資訊代表了特定的地理、政治或文化區,地區資訊可由一個**語言編碥(Language code)與可選的區域編碼(Country code)**來指定,其中語言編碼是 ISO-639 定義,由兩個小寫字母代表,例如”ca”表示嘉泰羅尼亞文(Catalan),”zh”表示中文(Chinese)。

區域編碼則由兩個大寫字母表示,定義 在ISO-3166, 例如IT表示義大利(Italy)、TW表示台灣(Taiwan)。


在React中的用法

安裝 react-intl

yarn add react-intl

使用 IntlProvider

將 <IntlProvider> 包在最外層,讓所有內部 component 都可以存取到它提供的屬性與方法。

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/437392de-810b-4b5f-a372-61413dc4e0ac/_2021-03-03_10.25.33.png

取得使用者語系並帶入 IntlProvider

接著:

  • 透過 navigator.language 取得使用者在瀏覽器上所使用的語系,並且將它代入 IntlProvider 的 local 屬性中
  • 若有需要可以定義 defaultLocale 屬性
https://s3-us-west-2.amazonaws.com/secure.notion-static.com/906d6305-1591-44be-86e7-d116b15440da/_2021-03-03_10.26.08.png

定義多語系字典檔

做好上述設定後,就可以來定義多語系用的字典檔。假設我們要做 i18n 的內容是範例頁面中的「Learn React」這個部分:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ab972b04-5e3d-4e3e-b36e-1af7e3ed2b62/_2021-03-03_10.03.32.png

這時候就可以先定義這個字典檔。首先在 ./src 資料夾內再新增一個 i18n 的資料夾,裡面分別放入 en.js, zh.js, ja.js:

https://i.imgur.com/1wP0IyE.png

接著分別定義每支字典檔的內容,這裡的 app.learn 可以視為 id,之後的使用 react-intl 提供的方法或組件時,他會根據你提供的這個 id 來帶入不同的內容,而 { } 刮起來的 name 表示它是動態的變數:

**// ./src/i18n/en.js**

const en = { 'app.learn': 'Learn {name}' };
export default en;
**// ./src/i18n/zh.js**

const zh_TW = { 'app.learn': '學習 {name}' };
export default zh_TW;
**// ./src/i18n/ja.js**

const ja_JP = { 'app.learn': '学び {name}' };
export default ja_JP;

撰寫切換語言的功能

因為一開始使用的是 functional component,想要添加狀態(state)的話,可以匯入 useState

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/fb2d9cec-6bf3-45f8-9450-6f4936a8bf23/_2021-03-03_10.27.09.png

在 App.js 的地方,撰寫三個按鈕可以來切換 locale 的狀態:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/a52fb65f-8e78-4ea2-92a6-e2a8eae56cc1/_2021-03-03_10.28.44.png

文字訊息多語系

這裡說明的是最一般用來轉換不同語系字串的作法,react-intl 提供了:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/f9dc8a6f-216d-4836-b435-c6329c0e39bd/_2021-03-03_10.30.05.png

根據不同的語言傳入不同的語系檔

可以切換 locale 的狀態後,最後就可以根據使用者選擇的語言傳入不同的語系檔。

先將剛剛撰寫好的語系檔載入:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/7d5ac671-1624-45ca-b201-7be4484eff15/_2021-03-03_10.33.32.png

接著定義 messages 這個變數,透過 if 判斷使用者切換到的語言為何,最後將 messages 傳入 <IntlProvider>:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4de68d48-d877-4576-9ff0-6fa2f0b7a1e8/_2021-03-03_10.42.40.png

在組件中使用語系檔

在 index.js 中,使用者在切換語言後,我們會提供不同的語系檔到 <IntlProvider> 的 messages 屬性內。現在,在 App.js 中就可以使用 react-intl 提供的 <FormattedMessage> 方法來顯示。

在 <FormattedMessage /> 中,id 會對應到先前寫在 ./src/i18n/ 資料夾內的語系檔中定義的屬性 app.learn,而 values 是因為在語系檔中有定義

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/7298abe6-8eac-47b1-8535-2540ec30c2f3/_2021-03-03_10.45.12.png

可以再使用 intl.formatMessage的方式,做一個歡迎使用者的文字:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/eb655036-a69f-47d3-8b6c-22c5b5af1723/_2021-03-03_10.55.08.png

要使用 intl.formatMessage ,要先引入 react-intl 的 hook :

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/19dd6172-342e-4fdd-a83c-b89d7f8b1e18/_2021-03-03_10.56.08.png

這時候就完成了簡單的 i18n 語系替換:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/6d0c0cad-6c9b-40ec-bf63-4fc1a3610984/_2021-03-03_10.54.09.png

時間日期多語系

在 react-intl 中也提供了時間、日期的多語系功能,包含:

  • <FormattedDate>
  • <FormattedTime>
  • <FormattedRelativeTime> :顯示距今或一段的時間長度 https://s3-us-west-2.amazonaws.com/secure.notion-static.com/5ffb8557-be9e-40c5-a0d6-8fa123a4cbb2/_2021-03-03_11.42.52.png

完成的結果如下:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/b42b1e71-b4e1-4dc5-9253-2fc707173493/_2021-03-03_11.42.09.png

如果有需要也可以使用 <FormattedRelativeTime>,這個方法會回傳距今的時間:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/d8ec85d4-bcf9-4d22-9a36-5e5888685f13/_2021-03-03_11.43.07.png

顯示的結果如下:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c7d344d9-d1c3-4bb6-a72b-4e8b37dcf573/_2021-03-03_11.43.23.png

數值多語系

若有需要針對數值進行多語系的切換,react-intl 則提供了:

  • <FormattedNumber>

其他Component

react-intl 還有很多不同的 Component 可以針對不同語言、語系做變化:

Components | Format.JS

For Vue

訂閱研究文章

Get updates and learn from the best

More To Explore

Scroll to Top

hurry up !

軟體工程師培訓

限時免費報名中

藉由與「真實世界軟體專案」相同的技術、工具與開發流程,化簡成與商業機密無關、門檻較低更容易上手的「模擬專案」,讓你有機會在職場前輩的陪伴下,完成真槍實彈的練習,動手解決真實的問題,快速累積個人的經驗與作品,而不只是「學習技術」而已。