ShadcnVueAdmin 的国际化是怎么实现的

用 vue-i18n 做中英文切换,整个方案只有 4 个文件。

前言

大家好,我是张大鹏。最近在开发 ShadcnVueAdmin 这个后台管理系统时,我做了一个功能:中英文切换。

国际化这个东西,说简单也简单,说复杂也能搞得很复杂。我最终的方案只用了 4 个文件,就实现了整个项目的中英文切换,包括语言持久化、语言切换组件、翻译文件管理。

今天把这套方案分享出来,如果你也在做 Vue3 项目的国际化,可以直接参考。

技术选型

Vue3 项目的国际化,主流方案就一个:vue-i18n。

ShadcnVueAdmin 用的是 vue-i18n v11+,搭配 VueUse 的 useStorage 做语言持久化。

为什么不用 vue-i18n 自带的持久化?因为 useStorage 更灵活,而且项目其他配置(主题、侧边栏状态)也都是用它来持久化的,保持统一。

整体结构

整个国际化方案就 4 个文件:

复制代码
src/plugins/i18n/
├── index.ts        # 类型定义、语言常量、持久化
├── setup.ts        # i18n 初始化
├── en.json         # 英文翻译
└── zh.json         # 中文翻译

src/components/
└── language-change.vue  # 语言切换组件

核心实现

1. 语言常量和持久化(index.ts)

这个文件定义了支持的语言、默认语言,以及语言偏好的持久化:

typescript 复制代码
import { useStorage } from '@vueuse/core'

export type Language = 'en' | 'zh'

export const SUPPORTED_LOCALES = new Set<Language>(['en', 'zh'])
export const DEFAULT_LOCALE: Language = 'en'

// 语言偏好持久化到 localStorage
export const appLocale = useStorage<Language>('app-locale', DEFAULT_LOCALE)

// 监听变化,防止设置不支持的语言
watch(appLocale, (newLocale) => {
  if (!SUPPORTED_LOCALES.has(newLocale)) {
    appLocale.value = DEFAULT_LOCALE
  }
}, { immediate: true })

useStorage 会自动把语言偏好存到 localStorage,key 是 app-locale。用户下次打开页面,会自动恢复上次选择的语言。

2. i18n 初始化(setup.ts)

typescript 复制代码
import { createI18n } from 'vue-i18n'
import { appLocale, DEFAULT_LOCALE } from '.'
import en from './en.json'
import zh from './zh.json'

export function setupI18n(app: App) {
  const i18n = createI18n({
    legacy: false,           // 使用 Composition API 模式
    locale: appLocale.value, // 从持久化中读取语言
    fallbackLocale: DEFAULT_LOCALE,
    messages: { zh, en },
  })
  app.use(i18n)
}

注意 legacy: false,这很重要。它让我们可以在 <script setup> 中使用 useI18n() 的 Composition API,而不是 Options API 的 this.$t()。

3. 翻译文件(en.json / zh.json)

翻译文件用嵌套的 JSON 结构,按功能模块组织:

json 复制代码
{
  "login": "登录",
  "email": "邮箱",
  "password": "密码",
  "marketing": {
    "hero": {
      "title": "每个0.01%的进化都在熔铸命运的质变...",
      "subtitle": "时光沙漏正迸发着惊雷..."
    },
    "features": {
      "title": "功能",
      "feature1": {
        "title": "使用现代技术",
        "description": "更加现代化的组件库,自由定制每一个组件"
      }
    }
  }
}

英文版结构完全对应,只是值不同:

json 复制代码
{
  "login": "Login",
  "email": "Email",
  "password": "Password",
  "marketing": {
    "hero": {
      "title": "Do you dare to use 365 days...",
      "subtitle": "The hourglass of time is bursting..."
    }
  }
}

4. 语言切换组件(language-change.vue)

vue 复制代码
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { appLocale, DEFAULT_LOCALE, SUPPORTED_LOCALES } from '@/plugins/i18n'

const { locale } = useI18n()

function handleLocaleChange(val: AcceptableValue) {
  if (typeof val !== 'string' || !SUPPORTED_LOCALES.has(val as Language)) {
    locale.value = DEFAULT_LOCALE
    appLocale.value = DEFAULT_LOCALE
    return
  }
  locale.value = val as Language
  appLocale.value = val as Language
}
</script>

关键点:切换语言时要同时更新两个地方 ------locale(vue-i18n 的当前语言)和 appLocale(持久化的语言偏好)。

在组件中使用

模板中用 $t():

vue 复制代码
<template>
  <h1>{{ $t('marketing.hero.title') }}</h1>
  <p>{{ $t('marketing.hero.subtitle') }}</p>
</template>

脚本中用 useI18n() 的 t():

vue 复制代码
<script setup>
const { t } = useI18n()

const features = [
  { title: t('marketing.features.feature1.title') },
  { title: t('marketing.features.feature2.title') },
]
</script>

总结

这套方案的核心思路:

  1. vue-i18n 负责翻译
  2. useStorage 负责持久化
  3. JSON 文件 负责翻译内容管理
  4. 一个组件 负责语言切换

4 个文件,干净利落。

如果你也在做 Vue3 项目的国际化,这套方案可以直接拿去用。只需要改一下 en.json 和 zh.json 的内容就行。

相关推荐
半个落月8 小时前
LangSmith 全链路观测(下):用 Dataset 与 LLM Judge 量化评估 RA
javascript·langchain
半个落月8 小时前
LangSmith 全链路观测(上):用 LangGraph 与 Milvus 构建可追踪的 RAG 客服
javascript·langchain
Java后端的Ai之路9 小时前
06-React-Props
前端·react.js·前端框架
半个落月9 小时前
LangChain.js Agent 中间件实战:生命周期、动态工具与文件权限
javascript·langchain
Flynt9 小时前
开源"间谍卫星"说数据全是真的,我把它的免key数据源挨个试了一遍
前端·开源·数据可视化
Csvn10 小时前
渲染管线
前端
程序员大阳10 小时前
副队长CSS教程(33)–圆角与透明
前端·css·透明·圆角
志尊宝10 小时前
Vue3 零基础每日笔记(082):文件上传实战——el-upload 校验、自定义上传、头像预览
前端·javascript·vue.js·笔记·#javascript·#vue.js
鬼手点金11 小时前
opencode-rules 插件
java·开发语言·前端·人工智能·chrome·git·github
柳杉11 小时前
借助 Codex 和可视化工作流,从调研到完整实现,3D 大屏竟然可以这么简单
前端·ai编程·数据可视化