Vue 项目做多语言支持用 vue-i18n,核心是:把文字抽成 key-value 的语言文件,组件里用 $t('key') 调用。
安装
npm install vue-i18n
创建语言文件
src/
├── locales/
│ ├── zh-CN.json
│ └── en-US.json
// zh-CN.json
{
"setup": {
"logout": "退出登录",
"language": "语言设置",
"version": "版本更新",
"clearCache": "清理缓存",
"darkMode": "暗黑模式"
},
"ok": "确定",
"cancel": "取消"
}
// en-US.json
{
"setup": {
"logout": "Logout",
"language": "Language",
"version": "Version Update",
"clearCache": "Clear Cache",
"darkMode": "Dark Mode"
},
"ok": "OK",
"cancel": "Cancel"
}
配置 i18n 实例
// src/i18n/index.ts
import { createI18n } from "vue-i18n";
import zhCN from "../locales/zh-CN.json";
import enUS from "../locales/en-US.json";
const savedLocale = localStorage.getItem("lang") || "zh-CN";
export const i18n = createI18n({
legacy: false, // 使用 Composition API 模式
locale: savedLocale,
fallbackLocale: "zh-CN",
messages: {
"zh-CN": zhCN,
"en-US": enUS,
},
});
// main.ts
import { createApp } from "vue";
import App from "./App.vue";
import { i18n } from "./i18n";
createApp(App).use(i18n).mount("#app");
组件内使用
Options API
<template>
<button @click="handleLogout">{{ $t('setup.logout') }}</button>
<span>{{ $t('ok') }}</span>
</template>
Composition API
import { useI18n } from "vue-i18n";
const { t } = useI18n();
console.log(t("setup.logout")); // "退出登录"
动态切换语言
import { useI18n } from "vue-i18n";
const { locale } = useI18n();
function switchLanguage(lang: string) {
locale.value = lang;
localStorage.setItem("lang", lang);
}
// 切换到英文
switchLanguage("en-US");
带参数的翻译
// zh-CN.json
{
"greeting": "你好,{name}!",
"items": "共 {count} 个项目"
}
<template>
<p>{{ $t('greeting', { name: 'Soulock' }) }}</p>
<p>{{ $t('items', { count: 42 }) }}</p>
</template>
语言列表组件示例
<template>
<div v-for="lang in languageList" :key="lang.id" @click="switchTo(lang)">
<span>{{ lang.label }}</span>
<span v-if="currentLang === lang.id">✓</span>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { useI18n } from "vue-i18n";
const { locale } = useI18n();
const languageList = [
{ id: "zh-CN", label: "简体中文" },
{ id: "en-US", label: "English" },
{ id: "ja-JP", label: "日本語" },
];
const currentLang = ref(locale.value);
function switchTo(lang: { id: string; label: string }) {
locale.value = lang.id;
currentLang.value = lang.id;
localStorage.setItem("lang", lang.id);
}
</script>
按需加载语言包
语言多时可以懒加载,避免全部打包:
async function loadLocale(lang: string) {
const messages = await import(`../locales/${lang}.json`);
i18n.global.setLocaleMessage(lang, messages.default);
i18n.global.locale.value = lang;
}
第一次切换到某语言时再加载对应文件,减小初始包体积。
