隨著國際化發展,多語言的需求越來越常見,單一的語言已經遠不能滿足需求了。作為一個組件庫,支持多語言也是基本能力。
多語言功能的本質其實是文本的替換,一個辭彙「OK」,在英文語境下是「OK」,日語語境下是「確認」,中文語境下可能是「確定」也可能是「確認」「好的」等等。
本文將以簡單組件為切入點,向大家展示Fusion組件庫是如何支持多語言的。
單組件的多語言
我們以一個常見的組件Search舉例,用戶輸入內容後可通過點擊「搜索」、「清除」按鈕觸發相應的事件,簡化代碼後如下:
class Search extends React.Component {
render() {
return (
<div>
<input />
<button>搜索</button>
<button>清除</button>
</div>
);
}
}
export default Search;
多語言處理最簡單直接的辦法是直接替換文本,不同語言環境下可能要將「搜索」替換為「search」、「サーチ」,將「清除」替換為「clear」、"クリア"等。同時作為一個組件庫,涉及到的大多是簡單辭彙而不是句子,因此我們首選配置化的方式:
// 抽取語言包
// search-en-us.js
{
search: search,
clear: clear
}
// search-zh-cn.js
{
search: 搜索,
clear: 清除
}
import searchZhCN from search-zh-cn;
class Search extends React.Component {
static propTypes = {
locale: PropTypes.object
};
static defaultProps = {
locale: searchZhCN
};
render() {
return (
<div>
<input />
<button>{locale.search}</button>
<button>{locale.clear}</button>
</div>
);
}
}
export default Search;
這樣就實現了單個組件Search的多語言支持。
但是,為每個組件對應一個語言包文件的做法顯然很不方便。Fusion Next作為一個PC端的React組件庫有50+組件,內置辭彙70多條,目前有13個組件需要國際化語言能力。
以語種為單位,將同一種語言下的映射關係放到一個文件里進行處理的方式更為高效。
多組件的多語言
為便於維護管理,增強可拓展性,我們以語種為單位抽取語言包。將同一語種下所有組件的語言對象{key: 文案}
放到一起,以displayName作為key,語言對象作為value,調整語言包如下:
// 抽取語言包
// zh-cn.js
{
Search: {
search: 搜索,
clear: 清除
},
Dialog: {},
...
}
這也是Fusion現在語言包的結構 https://unpkg.com/@alifd/next/lib/locale/zh-cn.js
由於語言包結構的調整,需要同時修改Search組件語言對象的默認值:
import zhCN from zh-cn;
class Search extends React.Component {
...
static defaultProps = {
locale: zhCN.Search
}
...
}
export default Search;
在使用時,用戶將語言包對象以props參數的形式傳給組件即可直接改變文案:
import jaJP from xxxx/ja-jp.js;
<Search locale={jaJP.Search}>
<Dialog locale={jaJP.Dialog}>
然而,在web應用越來越複雜的現在,很多項目里里可能會用到幾十甚至上百個組件,這樣給每個組件手動傳locale參數的方式一方面比較蠢,另一方面開發者需要關心locale參數,在語言切換時改變值的內容。
並且語言的設置大都是以項目(或者頁面)為單位的,有沒有更聰明、對開發者更友好的使用方式呢?
一鍵設置語言