1. 首页
  2. 前端

ant design pro vue、elementUI、iview和其他一些UI组件库中使用vue-i18n实现国际化语言切换多种方法总结

随着前端vue框架的日益成熟,越来越多的开发者选用vue作为前端项目框架,而项目中实现国际化也是网上也是五花八门,今天就将基于vue-i18n的国际化进行总结。

一、ant design pro vue组件库中实现国际化方法总结

1.安装ant-design-vue和vue-i18n包

npm install --save ant-design-vue
npm install vue-i18n --save

2.在src目录下新建i18n文件夹,并在i18n文件夹下创建zh_CN.js和en_US.js文件

例如:zh_CN.js文件:

import zh_CN from "ant-design-vue/es/locale-provider/zh_CN";
export default {
    ...zh_CN,
    'lang': '中文',
    'greet':'你好',
    'delete':'删除',
    'name':'姓名:{userName}'
}

en_US.js文件:

import en_US from "ant-design-vue/es/locale-provider/en_US"
export default {
    ...zh_CN,
    'lang': 'English',
    'greet':'hello',
    'delete':'delete',
    'name':'Name:{userName}'
}

3.main.js文件里面引入ant-design-vue和vue-i18n,和自定义语言包

import Antd from 'ant-design-vue'
import 'ant-design-vue/dist/antd.css'

import VueI18n from "vue-i18n"
import zh_CN from "./i18n/zh_CN"
import zh_US from "./i18n/en_US"
Vue.use(VueI18n)
Vue.use(Antd)

4.main.js文件里定义下面内容

const messages = {
    "zh_CN": zh_CN,
    "en_US": en_US,
}
const i18n = new VueI18n({
    locale: 'zh_CN', // 语言标识
    messages
})

5.vue实例中挂载i18n

new Vue({
  router,
  store,
  i18n,
  render: h => h(App)
}).$mount('#app')

6.入口文件(App.vue)处使用如下

<template>
   <locale-provider :locale='locale' >
        <div class='root'><router-view /></div>
     </locale-provider>
</template>

<script>
  import { LocaleProvider } from "ant-design-vue"
  export default {
    components: {
      LocaleProvider
    },
    computed: {
      locale() {
        return this.$i18n.messages[this.$i18n.locale];
      }
    }
  }
</script>

7.实现中英文切换

<button @click='changeLang'>语言切换</button>

changeLang() {
    this.$i18n.locale = this.$i18n.locale === "en_US" ? "zh_CN" : "en_US";
}

二、elementUI组件库实现国际化方法总结

对于element-ui的国际化,官方为了实现兼容vue-i18n,列出了多种实现国际化的方式,这里针对vue-i18n@6.x进行详解,其他的实现方式和这个大同小异。

1.安装element-ui和vue-i18n

npm install element-ui -S
npm install vue-i18n --save

2.src目录下新建与国际化相关的文件夹及文件

在src目录下新建i18n文件夹,i18n文件夹下面新建langs文件夹和i18n.js文件,langs文件夹下面新建zh.js、en.js和index.js文件,目录结构如图:

ant design pro vue、elementUI、iview和其他一些UI组件库中使用vue-i18n实现国际化语言切换多种方法总结

 

各文件内容如下:

zh.js文件:引入elementUI中的默认国际化文件,并自定义国际化文件,如下:

import zhLocale from 'element-ui/lib/locale/lang/zh-CN'
const zh = {
   ...zhLocale, // 或者用 Object.assign( { message: { 'greet':'你好' } }, zhLocale)
   message:{
      'greet':'你好'
   }
}
export default zh;

en.js文件:引入elementUI中的默认国际化文件,并自定义国际化文件,如下:

import enLocale from 'element-ui/lib/locale/lang/en'
const en = {
   ...enLocale, // 或者用 或者用 Object.assign( { message: { 'greet':'hello' } }, zhLocale)
   message:{
      'greet':'hello'
   }
}
export default en;

index.js文件:引入zh.js文件和en.js文件,并将文件暴露出去,代码如下:

import en from './en';
import zh from './zh';
export default {
   en: en,
   zh: zh
}

i18n.js文件:引入element-ui组件库、vue-i18n包和i18n/langs文件夹下面的index.js文件,并全局配置国际化,代码如下:

import Vue from 'vue'
import ElementUI from 'element-ui';  // 引入element-ui
import 'element-ui/lib/theme-chalk/index.css'; // element-ui主题
import VueI18n from 'vue-i18n';  // 引入国际化包
import messages from './langs';  // 引入i18n/langs下面的index.js文件,如果文件夹下面所引用文件是index.js,可以省略文件名,只写到该文件夹所属的目录即可

Vue.use( VueI18n )

const i18n = new VueI18n({
   locale: 'zh', // set locale
   messages, // set locale messages
})

Vue.use(ElementUI, {
   i18n: (key, value) =>i18n.t(key, value)
})

export default i18n

3.main.js中引入国际化文件

main.js文件中引入src目录下i18n中的i18n.js文件:

import i18n from './i18n/i18n'

4.vue实例中挂载i18n

new Vue({
   i18n,
   render: h => h(App),
}).$mount('#app')

5.实现中英文切换

<button @click='changeLang'>语言切换</button>

changeLang() {
    this.$i18n.locale = this.$i18n.locale==='zh'?'en':'zh'
}

到此,基于element-ui的兼容vue-i18n@6.x的国际化实现步骤完成,赶紧试试吧!

三、iview组件库实现国际化方法总结

对于iview组件库国际化的使用方式,和element-ui一模一样,可以按照element-ui的步骤进行即可,这里只对一些区别的进行借介绍。

1.安装iview和vue-i18n

npm install iview --save
npm install vue-i18n --save

2.src目录下新建国际化相关的文件夹及文件

这块可以完全参考element-ui的第2步骤。二对于一些区别,这里简要说明一下。
zh.js和en.js文件中,用iview提供的国际化文件替换element-ui中的那个文件,如下:

 import zhLocale from ‘element-ui/lib/locale/lang/zh-CN’; 
替换为:
import zhLocale from ‘iview/dist/locale/zh-CN’;

import enLocale from ‘element-ui/lib/locale/lang/en’; 
替换为:
import enLocale from ‘iview/dist/locale/en-US’;
index.js文件内容不变。

i18n.js文件:引入iview组件库、vue-i18n包和i18n/langs文件夹下面的index.js文件,并全局配置国际化,i18n.js完整代码如下:

import Vue from 'vue'

import iView from 'iview';
import 'iview/dist/styles/iview.css';

import VueI18n from 'vue-i18n';
import messages from './langs'

Vue.use(iView)
Vue.use(VueI18n)

const i18n = new VueI18n({
    locale: 'zh', // set locale
    messages, // set locale messages

})

Vue.locale = () => { };

export default i18n;

后面步骤与前面element-ui的3、4、5一模一样,详细请看上面的element-ui相关内容。

四、通用的基于vue-i18n的国际化方法总结

在做基于vue开发的项目,而不用任何UI组件库时,使用vue-i18n实现国际化,方法如下:

1.安装vue-i18n国际化包

npm install vue-i18n --save

2.src目录下新建与国际化相关的文件夹和文件

在src目录下新建i18n文件夹,i18n文件夹下面新建langs文件夹和i18n.js文件,langs文件夹下面新建zh.js、en.js和index.js文件,目录结构与element-ui和iview的目录结构一模一样。

zh.js文件如下:

const zh = {
    message: {
        greet:'你好'
    }
}
export default zh;

en.js文件如下:

const en = {
    message: {
       greet: 'hello'
    }
}
export default en;

index.js文件与前面几个组件库的index文件一样,如下:

import en from './en';
import zh from './zh';

export default {
    en: en,
    zh: zh
}

i18n.js文件如下:

import Vue from 'vue'

import VueI18n from 'vue-i18n'   // 引入国际化包
import messages from './langs' // 引入langs文件夹下面的index.js文件

Vue.use(VueI18n)

const i18n = new VueI18n({
    locale: 'zh', // set locale
    messages// set locale messages
})

export default i18n;

后面步骤与前面element-ui和iview的3、4、5一模一样,详细请看上面的element-ui相关内容。

import Vue from 'vue'
import App from './App.vue'
import i18n from './i18n/i18n'
Vue.config.productionTip = false
new Vue({
   i18n,
   render: h=>h(App),
}).$mount('#app')
<button @click="changeLangs">切换语言</button>
<span v-text="$t('message.greet')"></span>

changeLangs(){
    this.$i18n.locale=this.$i18n.locale==="zh"?"en":"zh";//关键语句
}

注:

1.实际上,vue-i18n国际化与你选用哪个UI组件库,或者是否使用UI组件库没有任何关系。而如果使用UI组件库的话,组件库会自带一些国际化语言包和封装了一些简单的国际化,会方便一点而已。不管使用什么UI组件库,vue-i18n的使用方法都是一样的。

2.对于博文中说的i18n国际化文件夹结构,这是没有固定要求的,我比较喜欢把i18n国际化模块单独抽离出来写,代码功能比较清晰。如果你不喜欢这种方式,也可以自己自行组建文件结构。

五.vue-i18n的语法及使用

(1).vue文件中使用方式:$t(“”)

   a. <span>{{$t('greet')}}</span>
   b. <span v-text="$t('greet')"></span>
   c. :placeholder="$t('greet')"

(2).js文件中使用方式:this.$t(“”)

   a. this.$message.success(this.$t('greet'))

   b. let obj={
        title:this.$t('hello'),
        content:this.$t('content)
      }

(3).传入变量

a.传入简单变量

如步骤2中zh_CN.jsen_US.js文件里面的‘name’字段中的变量userName

使用中传入参数:如:

<span> {{ $t('name', {'userName':'小明'} ) }} </span>  // 姓名:小明

也可以传入数组、对象等,如:
zh_CN.js中的字段:  'name': '姓名: {0}{1}'
// array $t('name', ['Jack', 'Job']) 
// object $t('name', {'0':'Jack', '1': 'Job'}}

b.复数格式(使用分隔符|

// messages: 
{
    us: {
        car: 'car | cars | {count} cars'
    }
}
$tc('car', x) // 选用不同的car类型

c.时间格式

const dateTimeFormats = {
  'us': {
    short: {
      year: 'numeric',
      month: 'short',
      day: 'numeric'
    },
    long: {
      year: 'numeric',
      month: 'short',
      day: 'numeric',
      weekday: 'short', 
      hour: 'numeric', 
      minute: 'numeric'
    }
  },
  cn: {
      //这里省略......
  }
}
// 需要放入配置项中
const i18n = new VueI18n({
    locale: 'zh_CN',
    messages,
    dateTimeFormats
})
// 使用
$d(new Date(), 'short')
$d(new Date(), 'long')
$d(new Date(), 'short', 'cn')

d.金额符号

const numberFormats = {
  'en-US': {
    currency: {
      style: 'currency',
      currency: 'USD'
    }
  },
  'ja-JP': {
    currency: {
      style: 'currency',
      currency: 'JPY',
      currencyDisplay: 'symbol'
    }
  }
}
// 同样也要加入配置项中
const i18n = new VueI18n({
  numberFormats
})
// 使用
$n(100, 'currency') // $100.00 
$n(100, 'currency', 'ja-JP') // ¥100

e.提供一个默认语言设置fallbackLocale(当某个语言不存在时,提供一个默认全的语言去处理)

const messages = {
  cn: {
    name: 'Name:'
  }
  us: {
  }
}
// us 的语言包中不存在 name , 我们默认cn,当us不存在时,使用cn的值
const i18n = new VueI18n({
  locale: 'us',
  fallbackLocale: 'cn',
  messages
})

f.v-t可以用于变量的引用,类似于$t(v-t 指令)

// 官网的列子
new Vue({
  i18n: new VueI18n({
    locale: 'en_US',
    messages: {
      en: { hello: 'hi {name}!' },
      cn: { hello: '嗨 {name}!' }
    }
  }),
  computed: {
    nickName () { return 'kazupon' }
  },
  data: { 
     path: 'hello' 
  }
}).$mount('#app')

<div id="app">
  <!-- literal -->
  <p v-t="{ path: 'hello', locale: 'cn', args: { name: 'kazupon' } }"></p>
  <!-- data biniding via data -->
  <p v-t="{ path: path, args: { name: nickName } }"></p>
</div>
// 结果如下:
<div id="app">
  <p>嗨 kazupon!</p>
  <p>hi kazupon!</p>
</div>

$t 与 v-t 对比:
1、$t是方法调用,v-t 是一个指令
2、v-t性能比$t更好,有自定义指令的缓存
3、$t使用更灵活,使用方法更简单

g.插入组件

如果遇到这样情况,如何处理?

<p>I accept xxx <a href=”/term”>Terms of Service Agreement</a></p>

第一反应是分成两个字段,a标签不属于翻译的内容,只要写成:

<p>{{ $t(‘xx1’) }}<a href=”/term”>{{ $t(‘xx2’) }}</a></p>

看了官网的介绍,说这种处理太笨拙了,可以通过组件的方式去处理

// 这里使用了i81n 组件
<i18n path="term" tag="label" for="tos">
    <a :href="url" target="_blank">{{ $t('tos') }}</a>
</i18n>
const messages = {
  en: {
    tos: 'Term of Service',
    term: 'I accept xxx {0}.'
  }
}
new Vue({
  el: '#app',
  i18n,
  data: {
    url: '/term'
  }
})

可以看到,仍然使用了两个变量存储信息,但是通过tag来生产标签,path来制定标签的内容。

更高级的用法,可以控制html元素的插入位置,通过place来指定出现在html中的位置。

<i18n path="info" tag="p">
    <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>

保留了语句的一体性,但是如果只是针对名词进行多语言的翻译,不对语法进行要求的话,可能使用不到。

h.动态加载语言包

一次加载所有的语言包是没有必要的,特别是语言包过多的情况下.

//i18n-setup.js
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import messages from '@/lang' // 语言包的地址,随项目本身设置修改
import axios from 'axios' // 根据项目中使用api请求模块去设置,不一定是axios

Vue.use(VueI18n)

export const i18n = new VueI18n({
locale: 'en', // set locale
  fallbackLocale: 'en', // 默认语言设置,当其他语言没有的情况下,使用en作为默认语言
  messages // set locale messages
})

const loadedLanguages = ['en'] // our default language that is prelaoded 

function setI18nLanguage (lang) {
i18n.locale = lang
  	axios.defaults.headers.common['Accept-Language'] = lang // 设置请求头部
document.querySelector('html').setAttribute('lang', lang) // 根元素增加lang属性
  	return lang
}

export function loadLanguageAsync (lang) {
if (i18n.locale !== lang) {
    if (!loadedLanguages.includes(lang)) {
return import(/* webpackChunkName: "lang-[request]" */ `@/lang/${lang}`).then(msgs => {
i18n.setLocaleMessage(lang, msgs.default)
        		loadedLanguages.push(lang)
        		return setI18nLanguage(lang)
})
    	} 
    	return Promise.resolve(setI18nLanguage(lang))
  }
  return Promise.resolve(lang)
}
// 在vue-router的beforeEach的全局钩子里处理
router.beforeEach((to, from, next) => {
  	const lang = to.params.lang
loadLanguageAsync(lang).then(() => next())
})

以上是目前已知的知识点,还有一些其他的用法,会继续扩充,整理中有什么错误,也欢迎下方留言,将及时更新。

原创文章,作者:Ferrycoln,如若转载,请注明出处:https://ms200.cn/archives/742

发表评论

电子邮件地址不会被公开。 必填项已用*标注

评论列表(1条)

  • 星星 2019年1月31日 上午10:09

    很全面,很不错,详细,完全都不用自己做了,按照这个步骤就实现了,赞!

联系我们

在线咨询:点击这里给我发消息

邮件:499661635@qq.com.com

工作时间:周一至周五,9:30-18:30

QR code