Vue I18n 实现语言的切换
·
Vue I18n
1. 什么是 Vue I18n?
Vue I18n 是 Vue.js 的官方国际化插件,它能够让你的应用轻松支持多种语言。无论是简单的文本替换,还是复杂的日期、数字格式化,Vue I18n 都能提供完善的解决方案。
2. 基础概念
2.1 安装与引入
npm install vue-i18n@9
2.2 最简单的 i18n 实例
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
// 1. 准备语言包
const messages = {
en: {
welcome: 'Welcome',
button: { submit: 'Submit' }
},
zh: {
welcome: '欢迎',
button: { submit: '提交' }
}
}
// 2. 创建 i18n 实例,这里是vue3的写法
const i18n = createI18n({
legacy: false, // 使用 Composition API 模式
locale: 'en', // 默认语言
messages // 上面的语言包
})
// 3. 挂载到 Vue 应用,同样是vue3
const app = createApp(App)
app.use(i18n)
app.mount('#app')
2.3 在组件中使用
Options API 方式:
<template>
<div>
<h1>{{ $t('welcome') }}</h1>
<button>{{ $t('button.submit') }}</button>
</div>
</template>
Composition API 方式:
<template>
<div>
<h1>{{ t('welcome') }}</h1>
<button>{{ t('button.submit') }}</button>
</div>
</template>
<script setup>
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
</script>
3. 例子
3.1 项目目录结构
src/
locales/ // 语言包目录
zh-CN.ts
en-US.ts
plugins/
i18n.ts // i18n 实例配置
composables/
useLocale.ts // 语言切换逻辑
components/
LangSwitch.vue //语言切换组件
3.2 模块化语言包
src/locales/zh-CN.ts
export default {
welcome: '欢迎使用',
chart: { title: '月度收支' },
btn: { lang: '切换语言' }
}
src/locales/en-US.ts
export default {
welcome: 'Welcome',
chart: { title: 'Monthly Report' },
btn: { lang: 'Change Language' }
}
3.3 带懒加载的 i18n 实例!
src/plugins/i18n.ts
import { createI18n } from 'vue-i18n'
/** 异步加载语言包 - 实现懒加载 */
export function loadLocaleMessages(locale: string) {
return import(/* @vite-ignore */`../locales/${locale}.ts`)
.then((module) => module.default) // 提取默认导出!!,import 返回的是一个promise对象
}
/** 从本地存储恢复语言设置 */
function getPersistedLocale(): string {
const saved = localStorage.getItem('locale')
if (saved) return saved
// 获取系统语言
const sysLang = navigator.language.slice(0, 2)
return sysLang === 'zh' ? 'zh-CN' : 'en-US'
}
const i18n = createI18n({
legacy: false, // 使用 Composition API
locale: getPersistedLocale(), // 智能初始语言
fallbackLocale: 'zh-CN', // 回退语言
messages: {} // 初始为空,动态填充
})
export default i18n
3.4 懒加载原理
为什么需要 .then(module => module.default)?
// 语言包使用默认导出
export default { welcome: 'Welcome' }
// 动态导入返回的模块对象:
import('../locales/en-US.ts').then(module => {
// module = { default: { welcome: 'Welcome' } }
const messages = module.default // 提取出真正的语言包
// messages = { welcome: 'Welcome' }
})
懒加载的网络请求过程:
首次加载应用:
GET /index.js # 主包(不含语言包)
用户切换到中文:
GET /chunks/zh-CN.[hash].js # 按需加载中文包
用户切换到英文:
GET /chunks/en-US.[hash].js # 按需加载英文包
3.5 应用初始化
src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import i18n, { loadLocaleMessages } from './plugins/i18n'
const app = createApp(App)
app.use(i18n)
// 关键:先加载语言包再挂载,避免首屏闪烁
loadLocaleMessages(i18n.global.locale.value).then((messages) => {
i18n.global.setLocaleMessage(i18n.global.locale.value, messages)
app.mount('#app') // 现在才挂载应用
})
3.6 语言切换逻辑
src/composables/useLocale.ts
import { ref } from 'vue'
import i18n, { loadLocaleMessages } from '@/plugins/i18n'
export function useLocale() {
// 响应式当前语言
const locale = ref(i18n.global.locale.value)
async function setLocale(lang: string) {
if (locale.value === lang) return // 防重复点击
// 1. 动态加载语言包
const messages = await loadLocaleMessages(lang)
// 2. 更新 i18n 实例
i18n.global.setLocaleMessage(lang, messages) // 添加语言包
i18n.global.locale.value = lang // 切换语言
// 3. 更新本地状态
locale.value = lang
// 4. 持久化存储
localStorage.setItem('locale', lang)
document.cookie = `locale=${lang}; path=/; max-age=31536000`
}
return { locale, setLocale }
}
3.7 语言切换组件
src/components/LangSwitch.vue
<template>
<select :value="locale" @change="setLocale($event.target.value)">
<option value="zh-CN">简体中文</option>
<option value="en-US">English</option>
</select>
</template>
<script setup lang="ts">
import { useLocale } from '@/composables/useLocale'
const { locale, setLocale } = useLocale()
</script>
3.8 在应用中使用
<template>
<div id="app">
<h1>{{ $t('welcome') }}</h1>
<p>{{ $t('chart.title') }}</p>
<button>{{ $t('btn.lang') }}</button>
<LangSwitch />
</div>
</template>
更多推荐


所有评论(0)