最近vue项目遇到需求,将项目全局国际化,要求中、英、日三种语言自由切换,在这里记录一下vue-i18n国际化语言包处理插件的使用,具体可参考: vue-i18n官方文档

1. 安装

npm install vue-i18n --save

2. 配置

src目录下新建i18n目录,en.js英文语言包,zh.js中文语言包,ja.js日文语言包。具体配置如下所示:

zh.js文件(具体配置可根据实际情况,但三个文件属性值必须一一对应)

module.exports = {
  common: {
    quanbu: '全部',
    zanwushuju: '暂无数据',
    qingxuanze: '请选择',
    qingshuru: '请输入',
    onlyNumber: '只能为数字',
    onlyAddress: '请输入正确邮箱地址',
    huoquzhong: '获取中...',
    }
}

en.js文件

module.exports = {
  common: {
    quanbu: 'all',
    zanwushuju: 'no data'
    }
}

ja.js文件

module.exports = {
  common: {
    quanbu: '全部',
    zanwushuju: '一時データなし',
    qingxuanze: '選ぶ',
    }
}

i18n目录下index.js文件

import Vue from 'vue'
import VueI18n from 'vue-i18n'
import locale from 'element-ui/lib/locale'
import zh from '@/common/lang/zh.js'
import en from '@/common/lang/en.js'
import ja from '@/common/lang/ja.js'
import zhLocale from 'element-ui/lib/locale/lang/zh-CN'
import enLocale from 'element-ui/lib/locale/lang/en'
import jaLocale from 'element-ui/lib/locale/lang/ja'

Vue.use(VueI18n)

const messages = {
  zh: Object.assign(zh, zhLocale),
  en: Object.assign(en, enLocale),
  ja: Object.assign(ja, jaLocale),
}
//将vuei18n实例化,并传入配置信息
const i18n = new VueI18n({
  locale: localStorage.getItem('locale') || 'zh', //当前语种,locale用来设置语种包
  messages,  //本地语言包
  fallbackLocale: 'zh', //当前语种不存在时,默认设置当前语种为中文
  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'  
      }
    }
  }
})
locale.i18n((key, value) => i18n.t(key, value)) //为了实现element插件的多语言切换

export default i18n

主入口文件main.js引入

import Vue from 'vue'
import App from '@/common/App.vue'
import router from '@/router'
import store from '@/store'
import i18n from '@/i18n' 
new Vue({
    router,
    store,
    i18n,
    render: h => h(App),
}).$mount('#app')

中、英、日语种切换

window.localStorage.removeItem('locale')
window.localStorage.setItem('locale', 'en') //'zh' 'ja'
window.location.reload()  //刷新当前页面,可能会从缓存中读取页面

3. i18n使用

  • $t 的使用(格式化)

简单使用:

//template 需要使用 {{}} 将 name包装起来
<div>{{$t('common.quanbu')}}</div>  //数据配置见zh.js文件
// js
this.$t('common.quanbu')//组件中使用

命名格式化:

const messages = {
  en: {
    common: {
      title: '全部, {name}'
    }
  }
}
<p>{{ $t('common.title', { name: '动物' }) }}</p> //输出:-->全部动物

//再例如:
const messages = {
  en: {
    common: {title: '{name1},{name2}你好'}
  }
}
<p>{{ $t('common.title', { name1: '张三',name1: '李四' }) }}</p>  //输出:-->张三,李四你好

> 注:在i18n使用动态变量时,$t的第二个参数是一个对象,所有在message中所需要动态添加的变量都在第二个参数中。

  • $tc 的使用 (复数)
const messages = {
  en: {
    apple: 'no apples | one apple | {count} apples',
    banana: 'no bananas | {n} banana | {n} bananas'
  }
}
//在组件内使用
<p>{{ $tc('apple', 2, { count: 10 }) }}</p> //-->10 apples
<p>{{ $tc('apple', 2) }}</p> // -->2 apples
<p>{{ $tc('apple', 10, { count: 10 }) }}</p> //-->10 apples
<p>{{ $tc('apple', 100) }}</p> // -->10 apples
 
<p>{{ $tc('banana', 1, { n: 1 }) }}</p> // -->1 banana
<p>{{ $tc('banana', 1) }}</p>  // -->1 banana
<p>{{ $tc('banana', 100, { n: 'too many' }) }}</p>  // ->>too many bananas

1、在定义复数时,必要使用|管道符分隔。使用管道分隔符时必须使用 $tc
2、当|管道符等于1个时,索引从1开始,最大索引为2;当管道符大于1个时,索引从0开始(类似数组),最大索引为管道符的个数
3、通过使用$tc(“复数”,index)获取对应语言文本

  • dateTimeFormats 日期时间格式化$d
//日期时间格式化配置
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'  
     }
   }
 }

$d的使用

//在组件中使用
  <p>{{ $d(new Date(), 'short') }}</p>
  <p>{{ $d(new Date(), 'long') }}</p>
  <p>{{ $d(new Date(), 'short','zh') }}</p>
  <p>{{ $d(new Date(), 'long', 'zh') }}</p>
 
//输出
Jul 31, 2022
Sat, Jul 31, 2022, 5:55 PM
 
2022072320180723日 周六 下午5:55
  • numberFormats 数字格式化$n
//数字格式化配置
 numberFormats:{ 
    'en': {
      currency: { 
        style: 'currency', currency: 'USD'
      }
    },
    'zh': {
      currency: {
        style: 'currency', currency: 'JPY', currencyDisplay: 'symbol'
      }
    }
  },

$n 的使用

  <p>{{ $n(100, 'currency') }}</p>  //-->$100.00
  <p>{{ $n(100, 'currency', 'zh') }}</p> //-->¥100

三个参数:

  • @param number 传入数字
  • @param path 调用的格式化方案
  • @param locale 使用语种,默认当前this.$i18n.locale

4. 常用方法

 this.i18n.getLocaleMessage('en')//获取全局某个语言的语言包,返回是一个对象
 this.$i18n.mergeLocaleMessage('zh', local.zh)//向全局中文语言包中补充内容

5. v-t 使用

//locale='en'
const messages = {
  en: {
    message: {title: hello'}
  },
  zh:{
   message: {title: '哈哈{name}'}
  }
}
//组件中使用1 字符串用法
 <p v-t="'message.title'"></p>   //--> hello
 //组件中使用2 对象用法
<p v-t="{ path: 'message.title', locale: 'zh', args: { name: 'wo' } }"></p>  //-->哈哈wo

v-t$t比较见链接: $t 与v-t的区别

1. $t 是扩展的Vue实例方法
优:在模板中灵活使用小胡子语法(mustash)语法{{}},也可以在Vue实例中灵活地使用计算道具和方法
缺:每次重新渲染时都会执行,因此它比较消耗性能。
2. v-t是一个自定义指令
优:当翻译一次时,由于其使用自定义指令进行缓存,因此具有比$t方法更好的性能。
缺: v-t不能灵活使用 $t,因为它相当复杂。已翻译的内容 v-t将插入到 textContent元素中。

6. 组件插值

组件插值用法详见链接: 基本用法和高级用法

//高级用法
<i18n path="info" tag="p">
	//limit、action控制插入位置,通过place来指定出现在html中的位置
    <span place="limit">{{ changeLimit }}</span>
    <a place="action" :href="changeUrl">{{ $t('change') }}</a>
</i18n>
 
const messages = {
  en: {
    info: 'You can {action} until {limit} minutes from departure.',
    change: 'change your flight',
    refund: 'refund the ticket'
  }
}
 
const i18n = new VueI18n({
  locale: 'en',
  messages
})
new Vue({
  i18n,
  data: {
    changeUrl: '/change',
    refundUrl: '/refund',
    changeLimit: 15,
    refundLimit: 30
  }
}).$mount('#app')
 
// result
<p>
    You can <a href="/change">change your flight</a> until <span>15</span> minutes from departure.
</p>
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐