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.tsen-US.tsplugins/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 APIlocale: 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>
