Vue I18n 是 Vue.js 的国际化插件----兼容 Vue.js 3.0.0+
unpkg.com 提供了一个基于 npm 的 CDN 链接。 上面的链接将始终指向 npm 上的最新版本。
<script src="https://unpkg.com/vue@3"></script>
<script src="https://unpkg.com/vue-i18n@9"></script>
<script type="module" src="https://unpkg.com/vue@3/dist/vue.esm-browser.js">
<script type="module" src="https://unpkg.com/vue-i18n@9/dist/vue-i18n.esm-browser.js">
npm install vue-i18n@9
yarn add vue-i18n@9
如果你想使用最新的开发版构建,就得从 GitHub 上直接 clone,然后自己构建一个 vue-i18n
git clone git@github.com:intlify/vue-i18n-next.git node_modules/vue-i18n
cd node_modules/vue-i18n
npm install # or `yarn`
npm run build # or `yarn run build`
main.js
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
import App from './App.vue'
const app = createApp(App) //创建Vue根实例
const messages = { //设置本地化的语言环境信息
zh: {
section: {
honor: '企业荣誉',
partner: '主要客户'
}
},
en: {
section: {
honor: 'honor',
partner: 'partner'
}
}
}
// 创建 i18n 实例
const i18n = createI18n({
locale: 'zh', //语言默认值
fallbackLocale: 'en', //备选语言
messages
})
app.use(i18n).mount('#app')
组件中
<template>
<section>
<h3>{{ $tc('section.honor') }}</h3>
</section>
<section>
<h3>{{ $t("section.partner") }}</h3>
</section>
</template>
通过更改locale的值即可实现不同语言切换
zh.js
export default {
// Vue i18n 支持复数 您需要定义具有管道的语言环境消息 |分隔符并在管道分隔符中定义复数
// 可以通过预定义的命名参数在语言环境消息中访问该数字 {count}和/或 {n}. 如有必要,您可以覆盖那些预定义的命名参数。
apple: '没有苹果 | 一个苹果 | {count} 苹果',
header: {
msg: '你好,世界!',
open: '打开弹窗',
close: '关闭弹窗'
},
section: {
honor: '企业荣誉',
partner: '主要客户',
culture: '企业文化',
person: {
name: '貂蝉',
job: {
type: '前端',
salary: '20k'
}
}
},
}
en.js
export default {
apple: 'no apple | one apple | {count} apple',
header: {
msg: '{Hi} World!',
open: 'Open Modal',
close: 'Clode Modal'
},
section: {
honor: 'Corporate honor',
partner: 'Major customers ',
culture: 'Corporate culture',
person: {
name: 'Mine cicada',
job: {
type: 'Web',
salary: '20K'
}
}
},
}
de.js
export default {
apple: 'Keine Äpfel | Ein Apfel | {count} Apfel',
header: {
msg: 'Hallo, Welt!',
open: 'Popup-Fenster öffnen',
close: 'Popup-Fenster schließen'
},
section: {
honor: 'Ehre des Unternehmens',
partner: 'Wichtige Kunden ',
culture: 'Unternehmenskultur',
person: {
name: 'Ornamente für Armeeoffiziermützen',
job: {
type: 'Frontend',
salary: '20k'
}
}
},
}
import { createI18n } from "vue-i18n";
import zh from './zh'
import en from './en'
import de from './de.js'
export default createI18n({
locale: 'zh', // 默认语言
fallbackLocale: 'en', // set fallback locale
messages: { // set locale messages
zh,
en,
de
}
})
console.log(zh, en, createI18n.allowComposition);
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
import i18n from './lang'
app.use(i18n).mount('#app')
html
<template>
<div class="lang">
<img :src="item.label" v-for="item in langData.lang" :key="item" alt="" @click="tollgeLang(item.value)" />
<!-- 也可以省略方法,直接赋值 --> <!-- @click='$i18n.locale = item.value' -->
</div>
<section>
<h3>{{ $t('section.honor') }}</h3>
</section>
<section>
<h3>{{ $t("section.partner") }}</h3>
</section>
<h4>
{{ $t("section.person.name") }}--{{ $t("section.person.job.type") }}--{{ $t("section.person.job.salary") }}
</h4>
<section>
<h3>{{ $t("section.culture") }}</h3>
</section>
<div class="apple">
<!-- 第一个参数是语言环境消息键,第二个参数是数值或对象 -->
<p>{{ $tc("apple", 0) }}</p>
<p>{{ $t("apple", 1) }}</p>
<p>{{ $tc("apple", 10, { count: "ten" }) }}</p>
</div>
</template>
css
<style scoped>
.lang {
display: flex;
justify-content: space-between;
margin-top: 20px;
float: right;
width: 146px;
}
.lang img {
width: 46px;
height: 30px;
}
</style>
JS
<script>
import { reactive } from "vue";
import { useI18n } from "vue-i18n";
export default ({
name: "I18n",
setup() {
// 这里使用的是 Vue + Vite 构建的项目,故以此导入图片
const chinese = new URL(`../assets/img/中国.jpeg`, import.meta.url).href;
// 通过字符串模板支持动态 URL
function getImageUrl(name) {
return new URL(`../assets/img/${name}.jpg`, import.meta.url).href;
}
// ES导入
/* lang: [
{label: require('@/assets/images/index/中国.jpg'), value: 'zh-CN'},
{label: require('@/assets/images/index/美国.jpg'), value: 'en-US'},
{label: require('@/assets/images/index/德国.jpg'), value: 'de-DE'}
] */
const langData = reactive({
lang: [
{ label: chinese, value: "zh" },
{ label: getImageUrl("美国"), value: "en" },
{ label: getImageUrl("德国"), value: "de" },
],
});
const { locale } = useI18n({ useScope: "global" });
console.log(useI18n(), locale, "=========", locale._value);
const tollgeLang = (item) => {
locale.value = item
}
return { langData, tollgeLang };
},
});
</script>
切换语言后,再次刷新页面,从 vuex
中获取语言信息,页面显示对应的语言
import { createStore } from 'vuex'
export default createStore({
state: {
locale: ''
},
mutations: {
setLanguage(state, payload) {
state.locale = payload.value;
window.localStorage.setItem('locale', payload.value);
},
changeLanguage(state, language) {
state.locale = language
}
},
actions: {
getLanguage(context) {
const language = window.localStorage.getItem('locale') || 'zh';
context.commit('changeLanguage', language)
}
},
})
import { createApp } from 'vue'
const app = createApp(App)
import store from './store'
import I18n from './language'
app.use(I18n).use(store).mount('#app')
延续上文的case(切记保存在 vuex
的时候 tollgeLang
传递的是一个对象)
import { onMounted } from "vue";
import { useI18n} from 'vue-i18n'
import { useStore } from 'vuex'
setup() {
const { locale } = useI18n()
const store = useStore()
const tollgeLang= (item) => {
locale.value = item.value
store.commit('setLanguage', locale)
}
onMounted(() => {
store.dispatch('language')
locale.value = store.state.isChangeLanguages
})
return { tollgeLang };
}