在 Vue 中使用 i18n 国际化

首先新建 src\locales 目录,编写两个国际化文件。

en-US.json

json 复制代码
{
  "greeting": "Hello World",
  "table": {
    "title": "Table Example",
    "description": "This is an application"
  },
  "buttons": {
    "toggleLanguage": "Toggle Language"
  },
  "currentLanguage": "Current Language"
}

zh-CN.json

json 复制代码
{
  "greeting": "你好,世界",
  "table": {
    "title": "表格示例",
    "description": "这是一个应用"
  },
  "buttons": {
    "toggleLanguage": "切换语言"
  },
  "currentLanguage": "当前语言"
}

新建 src\utils\i18n.ts 文件,编写国际化配置核心代码。

typescript 复制代码
import { match } from "@formatjs/intl-localematcher";
import { createI18n } from "vue-i18n";

export const i18n = createI18n({
  legacy: false,
  locale: "zh-CN",
});

/**
 * 支持的语言列表
 */
export const SUPPORTED_LOCALES = ["zh-CN", "en-US"];

/**
 * localStorage 中存储语言设置的键名
 */
const LOCALE_STORAGE_KEY = "locale";

/**
 * 切换全局语言
 * @param locale 目标语言区域设置,必须是支持的语言之一
 */
export const switchLanguage = async (locale: string) => {
  if (!SUPPORTED_LOCALES.includes(locale)) {
    throw new Error(`Unsupported locale: ${locale}`);
  }
  const { global } = i18n;
  switch (locale) {
    case "zh-CN":
      global.setLocaleMessage(locale, await import("../locales/zh-CN.json"));
      break;
    case "en-US":
      global.setLocaleMessage(locale, await import("../locales/en-US.json"));
      break;
  }
  global.locale.value = locale;
  const { documentElement } = document;
  documentElement.lang = locale;
  localStorage.setItem(LOCALE_STORAGE_KEY, locale);
};

/**
 * 根据浏览器语言设置切换到默认语言
 * 使用 @formatjs/intl-localematcher 进行标准化的语言匹配
 * 优先级:localStorage > 浏览器首选语言 > 浏览器其他语言 > 默认中文
 * 支持常见语言变体的智能匹配(如 zh-Hans → zh-CN,en-GB → en-US)
 */
export const switchDefaultLanguage = async () => {
  const languages = [...navigator.languages];
  const saved = localStorage.getItem(LOCALE_STORAGE_KEY);
  if (saved) languages.unshift(saved);
  const matched = match(languages, SUPPORTED_LOCALES, "zh-CN");
  await switchLanguage(matched);
};

随后即可在 src\main.ts 中使用 switchDefaultLanguage 函数进行初始语言设置。如果用户浏览器默认语言环境是英文,那么初次进入时即切换到英文。

如果使用了 element-plus,那么还需要根据语言环境加载组件库的语言包。

html 复制代码
<script setup lang="ts">
import { watchImmediate } from "@vueuse/core";
import dayjs from "dayjs";
import type { Language } from "element-plus/es/locale";
import elLocaleEn from "element-plus/es/locale/lang/en";
import { useI18n } from "vue-i18n";

const { locale } = useI18n();

const elLocale = ref<Language>();
const setElLocale = async (data: Promise<{ default: Language }>) => {
  elLocale.value = (await data).default;
};

watchImmediate(locale, async (locale) => {
  switch (locale) {
    case "zh-CN":
      await import("dayjs/locale/zh-cn");
      dayjs.locale("zh-cn");
      setElLocale(import("element-plus/es/locale/lang/zh-cn"));
      break;
    case "en-US":
      await import("dayjs/locale/en");
      dayjs.locale("en");
      elLocale.value = elLocaleEn;
      break;
  }
});
</script>

<template>
  <ElConfigProvider :locale="elLocale">
    <RouterView />
  </ElConfigProvider>
</template>
相关推荐
一 乐9 小时前
人口老龄化社区服务与管理平台|基于springboot+vue的人口老龄化社区服务与管理平台(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·人口老龄化社区服务与管理平台
喵个咪10 小时前
基于 Nuxt 4 的现代 Headless CMS 前端:架构深度解析与二次开发指南
前端·vue.js·nuxt.js
he___H12 小时前
B、B+树和vue部分知识
数据结构·vue.js·b树
书中枫叶12 小时前
我用 Vue3 写了一个 Chrome 步骤录制插件:自动截图、本地存储、一键导出教程
前端·vue.js
叶落阁主13 小时前
Vue3 中如何设计一套好用的 Icon 和 IconPicker 组件
前端·vue.js·icon
kungggyoyoyo13 小时前
从0开发一套geo优化软件:数据模型与API设计
前端·vue.js·后端
数据法师13 小时前
Alger Music Player 技术深度解析:基于 Electron + Vue 3 的开源网易云第三方客户端
vue.js·electron·开源
协享科技14 小时前
Vue 3 实现抖音式卡片滑动交互:从零到完整方案
前端·vue.js·交互·ai编程·英语·自考英语
_xaboy14 小时前
开源Vue组件FormCreate通过 JSON 生成TinyVue表单
前端·vue.js·低代码·开源·json·表单设计器
卤蛋fg615 小时前
给 vxe-table 设置全局默认参数:setConfig、setIcon 与 setTheme
vue.js