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文件,目录结构如图:
各文件内容如下:
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.js和en_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条)
很全面,很不错,详细,完全都不用自己做了,按照这个步骤就实现了,赞!