什么是国际化?
出于国际化的考虑,前端项目需要适应不同的语言和地区,倘若每种语言开发一套页面显然不现实,如果能在不修改内部代码的情况下,根据不同语言及地区显示相应的界面将会非常方便。
而i18n就是顺应这种思路的产物,其来源是英文单词 internationalization
的首末字符i
和n
,18为中间的字符数,是“国际化”的简称。我们将项目中的文案提取为变量并以合乎场景的名字命名,把这些变量对应翻译成各种语言的文案信息保存起来建立不同的语言包,应用时根据语言显示对应语言包的内容。
i18next
I18next是一个用JavaScript编写的国际化框架,提供了标准的i18n功能,并且支持各端应用。前端主流框架像Vue、Angular、React都有很完善且功能强大的插件对应支持,可以说你可以在任何应用中使用i18next来解决国际化。下面我就介绍一下i18next在几种前端框架下的使用方法。
Vue下使用i18next
好久没有搭建过Vue的项目,现在Vue CLI已经出到3了。而最近发现用npm安装依赖奇慢无比,所以这里改用yarn。
安装yarn
首先安装Homebrew:
1 | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" |
使用Homebrew安装yarn:
1 | brew install yarn |
新建项目
1 | yarn global add @vue/cli |
安装i18next
有关Vue的i18next插件有好几种,这里我们使用@panter/vue-i18next
。
安装i18next以及@panter/vue-i18next
:
1 | yarn add i18next |
i18next配置
安装好之后我们到main.js
中去配置:
1 | import Vue from 'vue' |
引入并安装@panter/vue-i18next
插件,i18next.init()
是i18next的初始化配置,lng
可以设置语言,fallbackLng
可以设置当找不到lng
语言对应的语言资源时选取一个默认的资源加载,然后创建i18n
对象并注入全局。
我们在locales
文件夹下新建两个语言资源文件:en.json
和zh.json
。
1 | // en.json |
1 | // zh.json |
在Age: {{num}}
这种写法中,num
为插值。
把这两个资源文件配置到resources
后我们的准备工作就都完成了。
使用i18next实现国际化
1 | <h1 v-html="$t('hello')"></h1> |
分别将语言设置为中文和英文我们可以得到对应的语言页面:
$t()
为全局方法用以转换语言键对应的内容,上面展示了i18next的普通输出、输出html标签以及传参的基本用法,不仅如此我们还可以在js中使用i18next:
1 | export default { |
切换语言
既然做国际化,那么切换语言的功能必不可少。我们在页面添加一个按钮,再写一个方法:
1 | changeLng() { |
i18next.language
获取当前语言,i18next.changeLanguage()
方法用来切换语言。使用效果如下:
i18next插件
i18next还提供了各式的插件用于满足开发者和用户的需求,这里介绍两个比较常用的。
为了避免一个资源文件后期过于庞大不便维护,我们可以将其按照功能模块拆分成多个文件,那么就不能在resources
里只引入一个文件,所以我们需要i18next-xhr-backend
。同时我们希望网页可以显示浏览器设置的语言,i18next也提供了一个名为i18next-browser-languagedetector
的插件。安装:
1 | yarn add i18next-xhr-backend |
配置:
1 | import Vue from 'vue' |
ns
表示加载的资源文件名数组集合,要注意语言资源的存放路径要在域名下可直接访问,loadPath
为资源路径。语言资源变成多文件后,使用时也要相应调整:
1 | <h2>{{ $t('user:name') }}</h2> |
defaultNS
表示如果不加user:
这样的文件名则默认去指定的文件寻找键值。
detection
下为i18next-browser-languagedetector
的配置,order
设置从何处读取语言,除了上面列出的url参数和浏览器设置,还有cookie
、localStorage
等;caches
表示以何种方式缓存语言设置。
Angular下使用i18next
其实我工作中使用i18next最多的框架就是Angular,但是该项目是基于Angular1.5的,实在是太古老了,关于Angular的i18next插件有三个:
三种插件的配置差别有点大,具体可以到他们的github上查看,在这里只贴出ng-i18next
的配置:
1 | window.i18next |
使用上ng2-i18next
类似于Vue,通过i18n.t('hello')
调用,ng-i18next
和angular-i18next
则基本相同,几种常用的用法如下:
1 | <p>{{'member:common.currency' | i18next}}</p> |
在js中可使用i18next.t('member:common.currency')
,这是个全局方法。
解决插值中字符被转义的问题
默认情况下,插值会被转义以避免可能的xss攻击。比如插入的变量为{ name: "blackstar's blog" }
,则转换后会输出blackstar's blog
。可以通过在键之前放置-
或在请求转换时将escapeValue
选项设置为false
来切换转义:
1 | { |
1 | i18next.t('user:name', { name: "blackstar's blog", interpolation: { escapeValue: false } }); |
当然你也可以在i18next.init()
初始化配置中将转义全局关掉,但并不建议,因为这样意味着你要自己对用户的输入进行校验防止xss攻击,所以只在特定的地方使用就好了。
结语
如果你只是要对项目进行基础的国际化那么本篇文章的内容应该足够你使用了,若还需更深入的拓展也可以到官网上查询API及其余插件的用法。