Vue 项目国际化(i18n)配置:vue-i18n 基础用法

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;
}

第一次切换到某语言时再加载对应文件,减小初始包体积。