小白学 VUE 系列Vue I18n 国际化插件使用教程
Vue I18n 是 Vue.js 的国际化插件
手册地址:https://kazupon.github.io/vue-i18n/zh/
安装
vue2版本
npm install vue-i18n@8
vue3
npm install vue-i18n@9
快速引入使用
在 src
下新建语言包 lang
文件夹,并创建语言包文件和引入文件index.jz,例如:zh.js
,en.js
lang
index.js
zh.js
en.js
index.js
import Vue from 'vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
import zh from './zh'
import en from './en'
const messages = {
en,
zh
}
const i18n = new VueI18n({
locale: 'zh', // 设置地区
messages, // 设置地区信息
})
export default i18n;
zh.js
export default{
main:{
message:"消息",
display:'显示'
}
}
en.js
export default{
main:{
message:"message",
display:'show'
}
}
main.js引入
new Vue({
router,
store,
i18n,
render: h => h(App)
}).$mount('#app')
调用
<template>
<div id="app">
<h1>{{ $t('main.message') }}</h1>
<select v-model="language" @change="changeLang">
<option value="zh">中文</option>
<option value="en">英文</option>
</select>
<router-view />
</div>
</template>
<script>
export default {
name:'App',
data() {
return {
language:''
}
},
methods: {
changeLang(){
console.log('改变语言',this.language)
this.$i18n.locale=this.language
}
}
}
</script>
语言包语法
对象形式传参
const messages = {
en: {
message: {
hello: '{msg} world'
}
}
}
<p>{{ $t('message.hello', { msg: 'hello' }) }}</p>
数组形式
const messages = {
en: {
message: {
hello: '{0} world'
}
}
}
<p>{{ $t('message.hello', ['hello']) }}</p>
含有html输出
const messages = {
en: {
message: {
hello: 'hello <br> world'
}
}
}
<p v-html="$t('message.hello')"></p>
复数
使用函数 $tc()
调用
可以通过预定义的命名参数 {count} 和/或 {n} 在语言环境信息中访问该数字
const messages = {
en: {
car: 'car | cars',
apple: 'no apples | one apple | {count} apples'
}
}
> 模板
<p>{{ $tc('car', 1) }}</p>
<p>{{ $tc('car', 2) }}</p>
<p>{{ $tc('apple', 0) }}</p>
<p>{{ $tc('apple', 1) }}</p>
<p>{{ $tc('apple', 10, { count: 10 }) }}</p>
输出如下:
<p>car</p>
<p>cars</p>
<p>no apples</p>
<p>one apple</p>
<p>10 apples</p>
日期
const dateTimeFormats = {
'en-US': {
short: {
year: 'numeric',
month: 'short',
day: 'numeric'
},
long: {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long',
hour: 'numeric',
minute: 'numeric'
}
},
'zh-CN': {
short: {
year: 'numeric',
month: 'short',
day: 'numeric'
},
long: {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long',
hour: 'numeric',
minute: 'numeric',
hour12: false
}
}
}
const i18n = new VueI18n({
dateTimeFormats
})
<div id="app">
<p>{{ $d(new Date(), 'short') }}</p>
<p>{{ $d(new Date(), 'long', 'zh-CN') }}</p>
</div>
如果没有定义 fallbackLocale 这个值,则默认显示是英文的格式,如果设置了中文,则显示中文
const i18n = new VueI18n({
locale: 'zh-CN', // 设置地区
messages, // 设置地区信息
dateTimeFormats,
fallbackLocale: 'zh-CN',
})
export default i18n;
<div id="app">
<p>{{ $d(new Date(), 'short') }}</p>
<p>{{ $d(new Date(), 'long', 'zh-CN') }}</p>
</div>
2023年6月10日
2023年6月10日星期六 21:35
数字本地化
可以使用你定义的格式来本地化数字。
const numberFormats = {
"en-US": {
currency: {
style: "currency",
currency: "USD",
},
},
"zh-CN": {
currency: {
style: "currency",
currency: "CNY",
},
},
"ja-JP": {
currency: {
style: "currency",
currency: "JPY",
currencyDisplay: "symbol",
},
},
};
const i18n = new VueI18n({
numberFormats
})
new Vue({
i18n
}).$mount('#app')
<div id="app">
<p>{{ $n(100, 'currency') }}</p>
<p>{{ $n(100, 'currency', 'zh-CN') }}</p>
</div>
回退本地化
总结:使用fallbackLocale:<lang>
选择首选语言缺少翻译时要使用的语言。
const i18n = new VueI18n({
locale: 'zh-CN',
fallbackLocale: 'en',
messages
})
如果默认找不到 zh-CN
翻译,则调用en
组件的本地化
因此你可以全局地在 Vue 的根实例以及任何被组合的组件中使用 $t 或者 $tc 进行翻译。当然面向 Vue 组件的设计,你也可以更方便的分别控制每个组件的语言环境信息
const Component1 = {
template: `
<div class="container">
<p>Component1 locale messages: {{ $t("message.hello") }}</p>
<p>Fallback global locale messages: {{ $t("message.greeting") }}</p>
</div>`,
i18n: { // `i18n` 选项,为组件设置语言环境信息
messages: {
en: { message: { hello: 'hello component1' } },
zh: { message: { hello: '你好 component1' } }
}
}
}
如果组件内定义了,则调用的话,则调用组件内的翻译。
组件的共享语言环境消息
import commonMessage from './locales/common' // 导入通用语言环境消息
export default {
name: 'ServiceModal',
template: `
<div class="modal">
<div class="body">
<p>This is good service</p>
</div>
<div class="footer">
<button type="button">
{{ $t('buttons.save') }}
</button>
</div>
</div>
`,
i18n: {
messages: { ... },
sharedMessages: commonMessages
}
}
自定义指令本地化
除了可以使用 $t
函数调用之外,还可以使用指令,例如v-t
v-t 比 $t 方法具有更好的性能,因为在一次翻译时自定义指令会进行缓存,$t 在每次重新渲染时都会被执行
div id="string-syntax">
<!-- 字符串 -->
<p v-t="'hello'"></p>
<!-- 通过数据进行键名路径绑定 -->
<p v-t="path"></p>
</div>
对象语法
<div id="object-syntax">
<!-- 文字 -->
<p v-t="{ path:'hello', locale:'ja', args: { name:'kazupon'} }"></p>
<!-- 通过 `data` 绑定数据 -->
<p v-t="{ path: path, args: { name: nickName } }"></p>
</div>
切换语言简单例子
<select v-model="locale" >
<option value="zh">中文</option>
<option value="en">英文</option>
</select>
export default {
name:'App',
data() {
return {
locale:'zh-CN'
}
},
watch: {
locale(val){
this.$i18n.locale=val
}
},
methods: {
}
}
懒加载语言包
一次加载所有翻译文件是过度和不必要的。使用 Webpack 时,延迟加载或异步加载转换文件非常简单
例如我们在创建了lang/index.js,语言包目录也在lang 下面,则例子如下:
import Vue from "vue";
import VueI18n from "vue-i18n";
Vue.use(VueI18n);
import zh from "./zh";
import en from "./en";
const messages = {
en,
"zh-CN": zh,
};
export const i18n = new VueI18n({
locale: "zh-CN", // 设置地区
messages, // 设置地区信息
fallbackLocale: "zh-CN",
});
const loadedLanguages = [i18n.locale] // 我们的预装默认语言
function setI18nLanguage(lang) {
i18n.locale = lang
document.querySelector('html').setAttribute('lang', lang)
return lang
}
export function loadLanguageAsync(lang) {
// 如果语言相同
if (i18n.locale === lang) {
return Promise.resolve(setI18nLanguage(lang))
}
// 如果语言已经加载
if (loadedLanguages.includes(lang)) {
return Promise.resolve(setI18nLanguage(lang))
}
// 如果尚未加载语言
return import(`@/lang/${lang}.js`).then(
messages => {
i18n.setLocaleMessage(lang, messages.default)
loadedLanguages.push(lang)
return setI18nLanguage(lang)
}
)
}
- 其中
@
表示src
目录
路由拦截一下
import {i18n,loadLanguageAsync} from './lang'
......
router.beforeEach((to, from, next) => {
const lang = to.params.lang || 'zh-CN';
loadLanguageAsync(lang).then(() => next())
})
new Vue({
router,
store,
i18n,
render: h => h(App)
}).$mount('#app')
版权提示
1.除了标识原创之外,其他可能来源于网友的分享,仅供学习使用2.如您发现侵犯了您的权利,请联系我们删除
3.转载必须带本文链接,否则你将侵权
4.关于会员或其发布的相关内容均由会员自行提供,会员依法应对其提供的任何信息承担全部责任,本站不对此承担任何法律责任
评论区 (0)
没有记录
请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!