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 的内容就行。

相关推荐
小天源26 分钟前
智叟云集系统 · 架构与职责分层
服务器·前端·数据库
Highcharts.js2 小时前
React 中原生支持使用 JSX 组件配置自定义表格 Highcharts Grid
前端·javascript·react.js·前端框架·jsx·highcharts·自定义表格
Java后端的Ai之路2 小时前
【AIAgent开发】-Agent工具封装成CLI(纯干货!!!)
java·javascript·人工智能·agent·cli
薛定谔的猫-菜鸟程序员2 小时前
Electron开发超详细教程(从入门到放弃)
前端·javascript·electron
最强小杰3 小时前
DeepSeek V4 Flash + Codex CLI 接入教程:原生 Responses API 适配,从配置到跑通收藏这篇就够了(2026)
java·前端·python·ai
静水leo3 小时前
使用 Whistle 拦截接口并模拟后端响应
前端
掘金者阿豪3 小时前
SQL Server数据迁移完成后,凌晨的数据库告警该怎么查?
前端·后端
小郎君6583 小时前
Vue 多标签页的加载态设计:为什么我没有用 Suspense 实现 PageLoading
vue.js·算法
JudithHuang3 小时前
React 嵌套路由与布局
前端·react.js·arcgis·react·react router