Published
Edited
Jul 28, 2020
Insert cell
md`# 国际化i18n实现`
Insert cell
md`## 实现思路

### 语言包
多语言包每个翻译用key来索引,key对应目标语言

### i18n
- 使用标签模版拿到不被翻译的变量
- 还原传入的字符串(\$\{1\} \$\{2\} ... 用作变量占位符⚠️)
- 根据key的生成规则找到对应key,进而找到要翻译的语言内容
- 将目标语言内容中的变量占位符用实际变量替换(replace方法逐个用变量替换 /\$\{(.+?)\}/i⚠️)
`
Insert cell
a = 'demo'
Insert cell
b = 'demommm'
Insert cell
langMap = ({})
Insert cell
// 模拟翻译平台录入的中文字符串
str = '开启${1}项目${2}';
Insert cell
// 生成key的规则
getKey=(text='')=>{
return text;
}
Insert cell
// 英文语言包
enMap = ({
[str]:'open ${1} product ${2}'
})
Insert cell
// 中文语言包
zhMap=({
[str]:str
})
Insert cell
// 模拟获取语言包api
requestLangApi = (lang)=>{
if(lang === 'en_US'){
return Promise.resolve(enMap);
}else{
return Promise.resolve(zhMap);
}
}
Insert cell
// 修改content内容
setContent=(value='')=>{
const el = document.getElementById('content');
el.innerHTML = value;
}
Insert cell
// 还原字符串

Insert cell
function i18n(strArr,...rest){
// 还原完整的字符串 需要把${1} ${2} ... 塞回去
const strContent = String.raw({raw:strArr},...(rest.map((v,i)=>{
return '${' + (i + 1) + '}';
})));
const key = getKey(strContent);
const langContent = langMap.langPkg[key] || '';
// 逐个匹配
const pattern = /\$\{(.+?)\}/i;
const result = rest.reduce((pre,cur)=>{
// 逐个替换掉对应变量的值
return pre.replace(pattern,cur);
},langContent);
setContent(result);
return result;
}
Insert cell
handleToggle = async(lang)=>{
langMap.langPkg = await requestLangApi(lang);
i18n`开启${a}项目${b}`;
}
Insert cell
html`<p id="content">xxx</p>`
Insert cell
handleToggle('zh_CN');
Insert cell
handleToggle('en_US');
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more