我正在参加「掘金·启航计划」
版本与模式
如果要使用vue3,则需要使用vue-i18n v9以上的版本
因为vue3支持组合式api(Composition API),因此vue-i18n从v9开始也增加了相应的支持
对于以前类似v8的使用方式,在v9里被叫做Legacy API模式,新的方式叫做Composition API模式。v9默认是Legacy API模式。可以在createI18n
时设置legacy: false
切换到Composition API模式
Legacy API使用
// 1. Ready translated locale messages
// The structure of the locale message is the hierarchical object structure with each locale as the top property
const messages = {
en: {
message: {
hello: 'hello world'
}
},
ja: {
message: {
hello: 'こんにちは、世界'
}
}
}
// 2. Create i18n instance with options
const i18n = VueI18n.createI18n({
locale: 'ja', // 设定语言
fallbackLocale: 'en', // 设定兜底的语言
messages, // 不同语言的文案
// If you need to specify other options, you can set other options
// ...
})
// 3. Create a vue root instance
const app = Vue.createApp({
// set something options
// ...
})
// 4. Install i18n instance to make the whole app i18n-aware
app.use(i18n)
// 5. Mount
app.mount('#app')
// Now the app has started!
于是,在每个组件中都可以使用this.$i18n
获取createI18n创建的i18n实例,使用this.$t
来获取对应语言的文案
在html中可以如下使用
<script src="https://unpkg.com/vue@3"></script>
<script src="https://unpkg.com/vue-i18n@9"></script>
<div id="app">
<p>{{ $t("message.hello") }}</p>
</div>
作用域
v9里增加了作用域的概念,一个叫全局作用域一个叫组件作用域,也就是说我们可以单独设置某个组件的语言,而忽略全局的语言
如果在创建i18n实例的时候指定了组件的选项,那么创建出来的就是组件作用域的i18n实例,它继承自全局的实例,并只在这个组件内有效
此时在组件内this.$i18n
获取的i18n实例就是组件自身的i18n实例。如果想要获得全局的实例需要使用i18n.global
(如果没有创建组件内部的i18n实例,那this.$i18n
和i18n.global
是相等的)
组件作用域的i18n实例并不意味着完全不受全局实例的影响。
- 组件内部的i18n实例没有指定语言,因此会兜底到全局的语言上去;
- 组件内部的i18n实例没有的文案,也会去全局的文案里去寻找;
- 如果没有设置
sync:false
,全局的语言改变,所有的组件i18n实例语言也都会变化(也就是说,组件语言变了不影响全局语言,全局语言变了影响组件语言)
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
// setting locale info used by global scope as an options
const i18n = createI18n({
locale: 'ja',
messages: {
en: {
message: {
hello: 'hello world',
greeting: 'good morning, world!'
}
},
ja: {
message: {
hello: 'こんにちは、世界',
greeting: 'おはよう、世界!'
}
}
}
})
// define component
const Component1 = {
template: `
<div id="component">
<h1>Component1</h1>
<p>Component1 locale messages: {{ $t("message.hello") }}</p>
<p>Fallback global locale messages: {{ $t("message.greeting") }}</p>
</div>
`,
i18n: { // 组件内的i18n实例构造参数,`this.$i18n`获取的就是这个实例
// locale: 'ja', 组件内部的i18n实例没有指定语言,因此会兜底到全局的语言上去
messages: {
en: { message: { hello: 'hello component1' } },
ja: { message: { hello: 'こんにちは、component1' } }
}
}
}
const app = createApp({
components: { Component1 }
})
app.use(i18n)
app.mount('#app')
切换语言
因为i18n分为全局作用域和组件作用域的,所以分开来看
没有创建组件内部的i18n实例,那this.$i18n
和i18n.global
是相等的
因此通过i18n.global.locale
和this.$i18n.locale
都可以改变语言
<template>
<div class="locale-changer">
<select v-model="$i18n.locale">
<option v-for="locale in $i18n.availableLocales" :key="`locale-${locale}`" :value="locale">{{ locale }}</option>
</select>
</div>
</template>
// when vue-i18n is being used with legacy: false, note that i18n.global.locale is a ref, so we must set it via .value:
i18n.global.locale.value = 'en'
// otherwise - when using legacy: true, we set it like this:
i18n.global.locale = 'en'
如果没有设置sync:false
,全局的语言改变,所有的组件i18n实例语言也都会变化(也就是说,组件语言变了不影响全局语言,全局语言变了影响组件语言)
于是通过i18n.global.locale
改变全局语言,此时所有的组件i18n实例语言也都会变化
// when vue-i18n is being used with legacy: false, note that i18n.global.locale is a ref, so we must set it via .value:
i18n.global.locale.value = 'en'
// otherwise - when using legacy: true, we set it like this:
i18n.global.locale = 'en'
通过this.$i18n.locale
改变组件的语言,其他组件语言不会变化
<template>
<div class="locale-changer">
<select v-model="$i18n.locale">
<option v-for="locale in $i18n.availableLocales" :key="`locale-${locale}`" :value="locale">{{ locale }}</option>
</select>
</div>
</template>