前言
在我们开发项目,尤其是涉及到国际化项目时,常常会提取出项目中使用的静态文本,使用语言包进行管理, 当切换语言设置的时候,整个项目的文字可以响应式的切换语种。
今天主要介绍的是当我们在使用
vue.js(2.x)
搭配Element-ui
开发项目时常用的国际化语言包处理插件——vue-i18n
安装
npm 安装
npm install vue-i18n --save复制代码
yarn 安装
yarn add vue-i18n --save复制代码
配置及使用
项目中vue-i18n的配置
常常一个项目中,我会以下列的结构来配置语言包:
lang/index.js
import Vue from 'vue'import VueI18n from 'vue-i18n'import Cookies from 'js-cookie'import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang导入Element的语言包 英文import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang g导入Element的语言包 中文import enLocale from './en' //导入该项目中用到的英文语言包import zhLocale from './zh'//导入该项目中用到的中文语言包Vue.use(VueI18n)const messages = { en: { ...enLocale, ...elementEnLocale }, zh: { ...zhLocale, ...elementZhLocale, lk:"asdasd {msg}"//测试 },}const i18n = new VueI18n({ locale: Cookies.get('language') || 'en', // 设置语种 messages, // 设置全局当地语言包, fallbackLocale: 'en', numberFormats:{ //设置 数字本地化 'en': { currency: { //添加 $ style: 'currency', currency: 'USD' } }, 'zh': { currency: { //添加 ¥ style: 'currency', currency: 'JPY', currencyDisplay: 'symbol' } } }, dateTimeFormats:{//设置 日期时间本地化 'en': { short: { year: 'numeric', month: 'short', day: 'numeric' }, long: { year: 'numeric', month: 'short', day: 'numeric', weekday: 'short', hour: 'numeric', minute: 'numeric' } }, 'zh': { short: { year: 'numeric', month: 'short', day: 'numeric' }, long: { year: 'numeric', month: 'short', day: 'numeric', weekday: 'short', hour: 'numeric', minute: 'numeric' } } }})export default i18n复制代码
在主入口文件main.js
中,也需要配置
import Vue from 'vue'import Element from 'element-ui'import 'element-ui/lib/theme-chalk/index.css'//导入配置好的国际化语言包import i18n from './lang' // InternationalizationVue.use(Element, { size: 'medium', // set element-ui default size设置元素默认大小 i18n: (key, value) => i18n.t(key, value)//在注册Element时设置i18n的处理方法})Vue.config.productionTip = false// 生产提示new Vue({ el: '#app', i18n, // 注入 配置好的国际化语言配置})复制代码
对于引入
VUE
,使用vue.use
,这个基本操作就不说什么喽...
但是要注意的是:在vue中注册i18n之后,我们便可以在组件中通过this.$i18n
获取到我们配置好的这个i18n对象
我们可以看的出来,将导入的
VueI18n
实例化,在new VueI18n()中传入配置信息:
- locale 当前语种
- fallbackLocale 如果当前语种不存在时,默认设置当前语种
- messages 本地语言包('en','zh'...)
- numberFormats 设置 数字格式化
- dateTimeFormats 设置 时间日期格式化 接下来一一介绍:
locale
主要是用来设置语种包,比如我们规定"en"代表英文语言包,那么在new VueI18n()中传入配置信息时,可以这样:
new VueI18n({ locale:'en'})复制代码
这里有一个细节点,案例中,我是这样配置的:
new VueI18n({ locale: Cookies.get('language') || 'en',})复制代码
原因:先在cookie中获取有没有之前设置的语种,如果设置过拿到设置的语种,如果还未设置,默认调用英文语言包.在整个项目中也是按照在用户设置语种后,将设置后的方案放到cookie中,以便下次用户使用时,自动获取上一次设置的语种。
项目中肯定会需要改变语种(这不废话么,否则干嘛使用它...),接下来我们就看看常用的改变语种的方法;
改变locale(语种)
1、通过实例化之后改变locale属性值
//lang.jsconst i18n new VueI18n({ locale: Cookies.get('language') || 'en',})export defult i18n//在组件中import i18n from "@/lang" //根据项目对应真实路径i18n.locale="zh" 改变为中文Cookies.set('language',"zh")//在cookie中存入设置复制代码
messages
接下来说一说最关键的一项,语言包.
我们一般会将项目中的静态语言分成产品所需要的各个语种,包括中文,英文,法文等...比如:
message:{ zh: { i18nView: { title: '切换语言', note: '目前只翻译了当前页面和侧边栏和导航,未完待续,敬请期待...', datePlaceholder: '请选择日期', tableDate: '日期', tableName: '姓名', tableAddress: '地址', default: '默认按钮', primary: '主要按钮', success: '成功按钮', info: '信息按钮', warning: '警告按钮', danger: '危险按钮' } }, en: { i18nView: { title: 'Switch Language', note: 'Currently only translated the i18n page and the sidebar and levelbar, please look forword to...', datePlaceholder: 'Pick a day', tableDate: 'tableDate', tableName: 'tableName', tableAddress: 'tableAddress', default: 'default:', primary: 'primary', success: 'success', info: 'info', warning: 'warning', danger: 'danger' } }}复制代码
其中 zh
就代表静态语言中文版,en
代表静态语言英文版.当然,如果项目很大的话,我们一般就将en
,zh
单独分成两个模块——en.js
,zh.js
.这样项目不仅结构变得更简洁明了,在维护开发阶段也节省很多时间.
// main.jsimport Vue from 'vue'import VueI18n from 'vue-i18n'Vue.use(VueI18n)const messages = { en: { message: { hello: 'How old are you?' } }, zh: { message: { hello: '怎么老是你?' } }}const i18n = new VueI18n({ locale: 'en', // set locale messages, // set locale messages})new Vue({ i18n }).$mount('#app')//组件中//输出{
{ $t("message.hello") }}复制代码How old are you?
上面例子中,在配置i18n中"en"代表了英文语种,在组件中通过
this.$t
这个方法来获取到我们配置好的语言包中的对应数据。
$t 的使用
简单来说就是拿到
messages
中的某个数据,参数是字符串,代表着所要获取的某一条数据
很多时候,我们需要的不是静态文本,往往需要的是一些可以动态添加的
[命名格式化]
const messages = { en: { message: { GG: '对{msg}不起' } }}//组件中使用{
{ $t('message.GG', { msg: '三要' }) }}//输出对三要不起
复制代码
这种叫做命名格式化,可以区域格式化信息。 这种情况下$t
的第二参数是一个对象,就代表了所有需要动态添加的内容,注意是所有在message
中所需要动态添加的变量都在第二个参数中。
我们来下下面几种情况
1.未传第二个参数
const messages = { en: { message: { GG: '{a}{b}哈哈' } }}//组件中使用1{
{ $t('message.GG') }}//输出{a}{b}哈哈
//组件中使用2{
{ $t('message.GG',{a:1,b:2) }}//输出12哈哈
复制代码
如上述例子中显示,如果未传第二个参数,那么将会都以按照字符串的形式展示.
2.不同的命名类型
const messages = { en: { message: { GG: '{a}{b}哈哈' } }}//组件中使用 数值型与字符串类型 1{
{ $t('message.GG',{a:1,b:"2") }}//输出12哈哈
//组件中使用2 对象类型{
{ $t('message.GG',{a:{},b:"2") }}//输出[object Object]2哈哈
//组件中使用3 数组类型(内含布尔,对象类型){
{ $t('message.GG',{a:[1,2,3,true,{}],b:"2") }}//输出123true[object Object]2哈哈
复制代码
总结一下下:
在组件中动态添加所需要的文本时:
- OBJECT对象类型会直接输出
[object Object]
- BOOlEAN布尔类型会按照字符串输出
true-->"true"/false-->"false"
- ARRAY数组类型中,如果每一项都是数值或者字符串那么直接输出,否则按上述情况显示
好了现在我要说的是,上面总结的几条规则,都是大废话,请不要记
因为这就是处理国际化语言包的工具包,语义化的意思很明确了,主要处理项目中的静态文本,没有人会傻到使用number
和string
之外类型的数据.
废话扯远了,接下来咱们扯回来,看一看另一个格式化方式
[列出格式]
话不多说,直接看例子吧,相信各位大佬一看就会。。
const messages = { en: { message: { hello: '{0}{1}{2}{3}{4}游过一群鸭' } }}// 组建内使用 1 数组方式{
{ $t('message.hello', ['门','前','大','桥','下']) }}//输出门前大桥下游过一群鸭
// 组建内使用 2 类似命名格式的方式{
{ $t('message.hello', { '0':"门",'1':'前','2':'大','3':'桥',4:'下 '}) }}//输出门前大桥下游过一群鸭
复制代码
$tc 的使用
我们往往需要多元化的复数,比如一个记录文件上传的状态
loadStatus
,值可能为已上传
和未上传
.如同下面例子
const messages = { zh: { loadStatus: '已经上传 | 未上传', size:'S | M | X | XXL' }}复制代码
这里必须注意一点:必须定义具有管道 |
分隔符的区域设置,并在管道分隔符中定义复数
//在组件内使用{
{ $tc('loadStatus',1) }}{
{ $tc('size',1) }}{
{ $tc('size',2) }}//输出已经上传MX复制代码
总结:
1、在定义复数时,必要使用
|
管道符分隔。2、当
|
管道符等于1个时,索引从1开始,最大索引为2;当管道符大于1个时,索引从0开始(类似数组),最大索引为管道符的个数3、通过使用
$tc(“复数”,index)
获取对应语言文本
numberFormats
numberFormats
是对象类型,是来设置数字格式化包括货币类型等.
numberFormats:{ 'en': { currency: { //添加 $ style: 'currency', currency: 'USD' } }, 'zh': { currency: { //添加 ¥ style: 'currency', currency: 'JPY', currencyDisplay: 'symbol' } } },复制代码
$n
对于数字格式化在组件中如何使用,如同$t
一样,也提供了对应的方法$n
.
//组件中使用{
{ $n(100, 'currency') }}{
{ $n(100, 'currency', 'zh') }} //输出$100.00
¥100
复制代码
$n(number,'path','locale')
方法,三个参数:
1.用户传入数字 必传2.调用的格式化方案 必传3.使用的语种,默认是当前this.$i18n.locale复制代码
dateTimeFormats
除了对于数字有格式化方案,对于日期时间也是有格式化方案的
dateTimeFormats:{//设置 日期时间本地化 'en': { short: { //显示英文 年月日 year: 'numeric', month: 'short', day: 'numeric' }, long: { //显示英文 年月日 星期 小时 分钟 year: 'numeric', month: 'short', day: 'numeric', weekday: 'short', hour: 'numeric', minute: 'numeric' } }, 'zh': { short: { year: 'numeric', month: 'short', day: 'numeric' }, long: { year: 'numeric', month: 'short', day: 'numeric', weekday: 'short', hour: 'numeric', minute: 'numeric' } } }复制代码
如果处理数字有
$n
方法,对于日期时间格式化也有对应的方法——$d
//在组件中使用//输出Aug 31, 2018Fri, Aug 31, 2018, 3:46 PM2018年8月31日2018年8月31日周五 下午3:46复制代码{
{ $d(new Date(), 'short') }}{
{ $d(new Date(), 'long') }}{
{ $d(new Date(), 'short','zh') }}{
{ $d(new Date(), 'long', 'zh') }}
其实这个就和处理数字格式化大同小异了,记住就好。 项目用到的可能不多,我习惯用Moment.js来处理时间日期
截止到这,对于messages的基本使用都介绍的差不多了。
常用方法
包括获取某个模块的语言包;区域语言包合并到全局语言包;
getLocaleMessage
this.i18n.getLocaleMessage('key')
,这个方法是用来获取全局语言包中某个语种的语言包,比如:
this.i18n.getLocaleMessage('en')//获取英文的语言包 返回的同样是一个对象复制代码
mergeLocaleMessage
this.i18n.mergeLocaleMessage('key',localeData)
,这是方法是用来对于 'key'语种中添加本地语言包,往往在某个子组件中,我们会将某个区域语言包合并到全局对应语种的语言包
this.$i18n.mergeLocaleMessage('zh', local.zh)//向全局中文语言包中补充内容复制代码
v-t
最后再说一下自定义指令v-t
.它和$t
作用一样,都是获取语言包中的某条数据,但也有很大的区别,稍后总结
v-t
的使用
//locale='en'const messages = { en: { message: { GG: hello' } }, zh:{ message: { GG: '哈哈{name}' } }}//组件中使用1 字符串用法 //输出 hello //组件中使用2 对象用法 //输出 哈哈lsq复制代码
总结:
字符串形式,只能简单的获取当前语种下的非动态文本数据 ,而对象用法支持设置语种,动态文本数据
v-t和$t的区别
$t 是扩展的Vue实例方法。它有以下优点和缺点:
[优点]
在模板中灵活使用小胡子语法(mustash)语法{
{}},也可以在Vue实例中灵活地使用计算道具和方法。[缺点]
每次重新渲染时都会执行,因此它比较消耗性能。
v-t是一个自定义指令。它有以下优点和缺点:
[优点]
当翻译一次时,由于其使用自定义指令进行缓存,因此具有比$t
方法更好的性能.
[缺点]
v-t不能灵活使用$t,因为它相当复杂。已翻译的内容v-t将插入到textContent元素中。
总结
此篇主要是简单讲了一些国际化vue-i18n
的简单配置和使用方法,对于动态加载之类的官方文档也讲的很清楚了。好了就到这里了,希望大家多多评论,有错误的地方还请各位大佬嘴下留情。mua