js端的国际化 多语言处理方案,
. 可以适配react(动态切换语言), 建议v16.12.0 以上版本
. 可以适配vue 2.x(动态切换语言), 建议v2.6.x 以上版本
. 在 Vue和 React 下由于页面业务复杂,允许子组件注册独立的 国际化模块
. 可以将android规范下的国际化多语言资源文件 strings.xml, 编译为自己所需要的js资源文件
复数判断参考 http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html
npm install i18n-xml-js --save
最简单的例子:
import I18nJs, {setLocal, addPluralization, plurals} from 'i18n-xml-js';
const en = {
"array": {
"cities": ["beijing", "shanghai", "jinan", "qingdao"]
},
// 复数
"plurals": {
"cardinal": {
"wastetime": {
"one": (...arg) => `${arg[0]} minute`,
"other": (...arg) => `${arg[0]} minutes`
}
},
"ordinal": {
takeRight: {
// zero,
one: (...args)=>`Take the ${args[0]}st right.`,
two: (...args)=>`Take the ${args[0]}nd right.`,
few: (...args)=>`Take the ${args[0]}rd right.`,
// many,
other: (...args)=>`Take the ${args[0]}th right.`
}
},
"range":{
days: {
other: (...args)=>`${args[0]}–${args[0]} days`
}
}
},
"string": {
"welcome_messages": (...arg) => `Hello, ${arg[0]}! You have ${arg[1]} new messages.`,
"app_name": "GetApps",
"pref_title_auto_update_market": "Update \"GetApps\" automatically",
"notif_button_update_all": "<font color=#ff6243>Update all</font>",
"btn_retry": "TRY AGAIN",
"btn_price": (...arg) => `¥${arg[0]}`,
"btn_progress": (...arg) => `${arg[0]}%%`,
"btn_pausable": "PAUSE",
"user_agreement_msg": (...arg) => `To use the basic features of this service, you must agree that us can collect, process, and use your personal data, including the personal balabalabalabala <a href=\"${arg[0]}\">Privacy Policy</a>. Agree?`
}
};
const zh={
"array": {
"cities": ["北京", "上海", "济南", "青岛"]
},
"plurals": {
"cardinal": {
"wastetime": {
"other": (...arg) => `${arg[0]} 分钟`
}
},
"ordinal": {
takeRight: {
// zero,
// many,
other: (...args)=>`选择第 ${args[0]} 个 权利.`
}
},
"range":{
days: {
other: (...args)=>`${args[0]}–${args[1]} 天`
}
}
},
"string": {
"welcome_messages": (...arg) => `你好, ${arg[0]}! 你有 ${arg[1]} 条消息.`,
"app_name": "应用商店",
"pref_title_auto_update_market": "自动更新 \"应用商店\"",
"notif_button_update_all": "<font color=#ff6243>升级所有应用</font>",
"btn_retry": "再试一下",
"btn_price": (...arg) => `¥${arg[0]}`,
"btn_progress": (...arg) => `${arg[0]}%%`,
"btn_pausable": "暂停",
"user_agreement_msg": (...arg) => `好长一段文字呀,啦啦啦阿拉蕾 <a href=\"${arg[0]}\">快快快快快快</a>. 同意吗?`
}
};
// 设置显示语言。默认就是en
setLocal('en')
// 'en' 相当于备用语言,如果en里有些字段没有,则用zh里的显示
const i18n = I18nJs({en, zh}, 'en')
const lang = i18n.lang;
// 获取一个字段
lang.string.app_name // GetApps
lang.array.cities[0] // beijing
// 有参数的字段
lang.string.welcome_messages('小明', 20) //Hello, 小明! You have 20 new messages.
// 处理复数
// 基础的复数, 第一个数字用于判断复数类型,后边的参数用于模板字符串
plurals.cardinal(lang.plurals.cardinal.wastetime, 5, 5) // 5 minutes
plurals.cardinal(lang.plurals.cardinal.wastetime, 1, 1) // 1 minute
//序数复数, 第一个数字用于判断复数类型,后边的参数用于模板字符串
plurals.cardinal(lang.plurals.ordinal.takeRight, 5, 5) // Take the 5th right.
plurals.cardinal(lang.plurals.ordinal.takeRight, 1, 1) // Take the 1st right.
// 区间复数 第一、二个数字用于判断复数类型,后边的参数用于模板字符串
plurals.range(lang.plurals.range.days, 1, 2, 1, 2) // 1–2 days
// addPluralization(pluralization)
// i18n-xml-js 默认的复数解析规则只有 en(英语),zh(中文),姚添加其它语言的,就需要用到 addPluralization
// 增加日语的复数判断器
addPluralization({
ja: {
// 基本复数
cardinal: (count)=>{
if (count == 0) {
return 'zero'
}
return 'other'
},
// 序数复数
ordinal: (count)=>{
return 'other'
},
// 区间复数
range: (count1, count2)=>{
return 'other'
}
}
})
//**复数判断参考**
//http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html
具体可以参考 react-example 需要注意的是Android下边没有基于序数和区间的复数规则~ 所以编译出的文件复数只有plurals.cardinal
package.json 添加scriprs 命令 npm run parseFormXML
"scripts": {
"parseFormXML": "parseFromXML i18n/**/*.xml"
},
zh.xml
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string-array name="citys">
<item>北京</item>
<item>上海</item>
<item>济南</item>
<item>青岛</item>
</string-array>
<plurals name="wastetime">
<item quantity="one">%d 分钟</item>
<item quantity="other">%d 分钟</item>
</plurals>
<string name="welcome_messages">你好, %1$s! 你有 %2$d 新消息.</string>
<string name="app_name" translatable="false">应用市场</string>
<string name="pref_title_auto_update_market">自动更新 "应用市场"</string>
<string name="notif_button_update_all"><![CDATA[<font color=#ff6243>更新全部</font>]]></string> <!--仅海外按钮高亮-->
<string name="btn_retry">再试一次</string>
<string name="btn_price">¥<xliff:g id="priceNumber">%1$s</xliff:g></string>
<string name="btn_progress"><xliff:g id="precentage">%1$d</xliff:g>%%</string>
<string name="btn_pausable">暂停</string>
<string name="user_agreement_msg"><![CDATA[To 要使用本应用基础服务, 你需要同意本应用搜集和使用您的个人信息, 巴拉巴拉吧啦 <a href=\"%1$s\">隐私政策</a>. 您是否同意?]]></string>
</resources>
output: zh.js
const local = {
"array": {
"citys": ["北京", "上海", "济南", "青岛"]
},
"plurals": {
"cardinal": {
"wastetime": {
"one": (...arg) => `${arg[0]} 分钟`,
"other": (...arg) => `${arg[0]} 分钟`
}
}
},
"string": {
"welcome_messages": (...arg) => `你好, ${arg[0]}! 你有 ${arg[1]} 新消息.`,
"app_name": "应用市场",
"pref_title_auto_update_market": "自动更新 \"应用市场\"",
"notif_button_update_all": "<font color=#ff6243>更新全部</font>",
"btn_retry": "再试一次",
"btn_price": (...arg) => `¥${arg[0]}`,
"btn_progress": (...arg) => `${arg[0]}%%`,
"btn_pausable": "暂停",
"user_agreement_msg": (...arg) => `要使用慈祥基础服务, 你需要同意本应用搜集和使用您的个人信息, 巴拉巴拉吧啦 <a href=\"${arg[0]}\">隐私政策</a>. 您是否同意?`
}
};
export default local;
国际化多语言实例工厂
import I18nJs from 'i18n-xml-js';
//...
// I18nJs({语言资源对象}, '备用语言(一定要选择语言资源对象 里有的key)')
const i18n = I18nJs({en, zh, /* ..其他语言.. */}, 'en')
设置当前语言
import {setLocal} from 'i18n-xml-js';
//...
// setLocal('当前语言')
setLocal('en')
增加复数判断器 ,i18n-xml-js 默认只包含en(英语),zh(中文)的复数判断器
import {addPluralization} from 'i18n-xml-js';
//...
// addPluralization({复数规则解析对象})
addPluralization({// 增加日语的复数判断器
ja: {
// 基本复数
cardinal: (count)=>{
if (count == 0) {
return 'zero'
}
return 'other'
},
// 序数复数
ordinal: (count)=>{
return 'other'
},
// 区间复数
range: (count1, count2)=>{
return 'other'
}
}
})
当前语言下的复数判断器
import {plurals} from 'i18n-xml-js';
//...
// 基础的复数, 第一个数字用于判断复数类型,后边的参数用于模板字符串
plurals.cardinal(lang.plurals.cardinal.wastetime, 5, 5) // 5 minutes
plurals.cardinal(lang.plurals.cardinal.wastetime, 1, 1) // 1 minute
//序数复数, 第一个数字用于判断复数类型,后边的参数用于模板字符串
plurals.cardinal(lang.plurals.ordinal.takeRight, 5, 5) // Take the 5th right.
plurals.cardinal(lang.plurals.ordinal.takeRight, 1, 1) // Take the 1st right.
// 区间复数 第一、二个数字用于判断复数类型,后边的参数用于模板字符串
plurals.range(lang.plurals.range.days, 1, 2, 1, 2) // 1–2 days