多语言技术方案架构

整体架构图

┌─────────────────┐                      ┌─────────────────┐
│                 │                      │                 │
│     前端层      │                      │     后端层      │
│                 │                      │                 │
└────────┬────────┘                      └────────┬────────┘
         │                                        │
         │                                        │
         ▼                                        ▼
┌─────────────────┐                      ┌─────────────────┐
│  Vue I18n 管理  │                      │  国际化资源文件  │
│                 │◄────── API 请求 ─────►│  多语言数据库   │
│ 本地化资源文件   │    (带语言标识)      │  翻译服务       │
└─────────────────┘                      └─────────────────┘
         │                                        │
         │                                        │
         ▼                                        ▼
┌─────────────────────────────────────────────────────────┐
│                                                         │
│                   多语言内容展示                         │
│                                                         │
└─────────────────────────────────────────────────────────┘

前端多语言详细架构图

┌─────────────────────────────────────────────────────────────────────────────┐
│                                  Vue 应用                                    │
└───────────────────────────────────┬─────────────────────────────────────────┘
                                    │
                                    │ 注册
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                                  Vue I18n                                    │
│                                                                             │
│  ┌───────────────────┐     ┌───────────────────┐    ┌────────────────────┐  │
│  │    Composition    │     │     Options       │    │   插件注册机制     │  │
│  │       API         │     │      API          │    │   app.use(i18n)    │  │
│  │   useI18n() 钩子  │     │   $t(), $tc()     │    │                    │  │
│  └───────────────────┘     └───────────────────┘    └────────────────────┘  │
│                                                                             │
└───────────────┬─────────────────────┬──────────────────────┬───────────────┘
                │                     │                      │
                ▼                     ▼                      ▼
┌───────────────────────┐  ┌─────────────────────┐  ┌─────────────────────────┐
│    语言资源管理       │  │   本地存储机制      │  │     动态语言切换        │
│                       │  │                     │  │                         │
│ ┌─────────────────┐   │  │ ┌───────────────┐   │  │ ┌───────────────────┐  │
│ │  语言包文件     │   │  │ │ localStorage  │   │  │ │  setLocale()      │  │
│ │  zh-CN.js      │   │  │ │ 存储当前语言   │   │  │ │  切换语言函数     │  │
│ │  en-US.js      │   │  │ │ 设置           │   │  │ │                   │  │
│ └─────────────────┘   │  │ └───────────────┘   │  │ └───────────────────┘  │
│                       │  │                     │  │                         │
│ ┌─────────────────┐   │  │ ┌───────────────┐   │  │ ┌───────────────────┐  │
│ │ 日期时间格式    │   │  │ │ 浏览器语言    │   │  │ │ HTML lang 属性    │  │
│ │ 数字格式        │   │  │ │ 检测机制      │   │  │ │ 自动更新          │  │
│ │ 货币格式        │   │  │ │              │   │  │ │                   │  │
│ └─────────────────┘   │  │ └───────────────┘   │  │ └───────────────────┘  │
└───────────────────────┘  └─────────────────────┘  └─────────────────────────┘
          │                          │                         │
          └──────────────────────────┼─────────────────────────┘
                                     │
                                     ▼
┌────────────────────────────────────────────────────────────────────────────┐
│                             组件层多语言应用                               │
│                                                                            │
│  ┌────────────────────┐   ┌────────────────────┐   ┌─────────────────────┐ │
│  │   文本国际化       │   │    图片国际化      │   │   格式化国际化      │ │
│  │                    │   │                    │   │                     │ │
│  │ ┌──────────────┐   │   │ ┌──────────────┐   │   │ ┌───────────────┐  │ │
│  │ │ {
   
   { $t(...) }}│   │   │ │ :src=$t(...)  │   │   │ │ {
   
   { d(...) }} │  │ │
│  │ │ 模板中使用    │   │   │ │ 动态绑定图片  │   │   │ │ 日期格式化   │  │ │
│  │ └──────────────┘   │   │ └──────────────┘   │   │ └───────────────┘  │ │
│  │                    │   │                    │   │                     │ │
│  │ ┌──────────────┐   │   │ ┌──────────────┐   │   │ ┌───────────────┐  │ │
│  │ │ t('...')     │   │   │ │ 图片目录结构 │   │   │ │ {
   
   { n(...) }} │  │ │
│  │ │ JS中使用     │   │   │ │ 按语言区分   │   │   │ │ 数字格式化   │  │ │
│  │ └──────────────┘   │   │ └──────────────┘   │   │ └───────────────┘  │ │
│  └────────────────────┘   └────────────────────┘   └─────────────────────┘ │
└────────────────────────────────────────────────────────────────────────────┘
                                     │
                                     ▼
┌────────────────────────────────────────────────────────────────────────────┐
│                             接口请求与后端交互                              │
│                                                                            │
│  ┌────────────────────────┐    ┌────────────────────────────────────────┐  │
│  │     请求拦截器         │    │              响应处理                  │  │
│  │                        │    │                                        │  │
│  │  添加语言标识头        │    │   处理多语言数据                      │  │
│  │  Accept-Language       │    │   动态更新UI                          │  │
│  └────────────────────────┘    └────────────────────────────────────────┘  │
└────────────────────────────────────────────────────────────────────────────┘

后端多语言详细架构图

┌───────────────────────────────────────────────────────────────────────────────┐
│                               后端服务层                                       │
└───────────────────────────────────┬───────────────────────────────────────────┘
                                    │
                                    │ 请求处理
                                    ▼
┌───────────────────────────────────────────────────────────────────────────────┐
│                            语言识别与处理中间件                               │
│                                                                               │
│  ┌────────────────────────┐  ┌────────────────────────┐  ┌─────────────────┐ │
│  │ Accept-Language 解析   │  │   语言区域设置         │  │  语言回退策略   │ │
│  │                        │  │                        │  │                 │ │
│  │ 提取客户端语言标识     │  │ 设置当前请求的语言环境 │  │ 不支持语言的    │ │
│  │ zh-CN, en-US 等        │  │ req.locale = 'zh-CN'   │  │ 默认处理机制   │ │
│  └────────────────────────┘  └────────────────────────┘  └─────────────────┘ │
└───────────────────────────────────┬───────────────────────────────────────────┘
                                    │
                                    ▼
┌───────────────────────────────────────────────────────────────────────────────┐
│                              多语言数据存储层                                  │
│                                                                               │
│  ┌────────────────────────────────────┐  ┌───────────────────────────────────┐│
│  │           数据库设计               │  │          缓存策略                 ││
│  │                                    │  │                                   ││
│  │ ┌──────────────────────────────┐   │  │ ┌────────────────────────────┐   ││
│  │ │       单表JSON字段方案       │   │  │ │        Redis缓存           │   ││
│  │ │ {                            │   │  │ │                            │   ││
│  │ │   "zh-CN": "产品名称",       │   │  │ │  多语言内容缓存           │   ││
│  │ │   "en-US": "Product Name"    │   │  │ │  减少数据库查询           │   ││
│  │ │ }                            │   │  │ │                            │   ││
│  │ └──────────────────────────────┘   │  │ └────────────────────────────┘   ││
│  │                                    │  │                                   ││
│  │ ┌──────────────────────────────┐   │  │ ┌────────────────────────────┐   ││
│  │ │       关联表方案             │   │  │ │     缓存更新机制           │   ││
│  │ │                              │   │  │ │  语言数据变更时            │   ││
│  │ │  主表 + 翻译表               │   │  │ │  自动刷新缓存              │   ││
│  │ │  一对多关系                  │   │  │ │                            │   ││
│  │ └──────────────────────────────┘   │  │ └────────────────────────────┘   ││
│  └────────────────────────────────────┘  └───────────────────────────────────┘│
└───────────────────────────────────┬───────────────────────────────────────────┘
                                    │
                                    ▼
┌───────────────────────────────────────────────────────────────────────────────┐
│                              数据处理与响应层                                  │
│                                                                               │
│  ┌────────────────────────────────┐    ┌─────────────────────────────────────┐│
│  │       查询适配器               │    │           响应格式化                ││
│  │                                │    │                                     ││
│  │  根据当前语言环境              │    │  统一响应格式                      ││
│  │  动态构建查询条件              │    │  处理多语言字段                    ││
│  │  SELECT ... WHERE locale = ?   │    │  处理特殊字符编码                  ││
│  └────────────────────────────────┘    └─────────────────────────────────────┘│
│                                                                               │
│  ┌────────────────────────────────┐    ┌─────────────────────────────────────┐│
│  │      翻译服务集成              │    │           多语言日志               ││
│  │                                │    │                                     ││
│  │  对缺失翻译的内容              │    │  记录语言相关问题                  ││
│  │  调用第三方翻译API进行翻译     │    │  便于后期分析和优化                ││
│  │  如Google Translate API        │    │  监控翻译覆盖率                    ││
│  └────────────────────────────────┘    └─────────────────────────────────────┘│
└───────────────────────────────────────────────────────────────────────────────┘

完整多语言交互流程图

┌──────────────┐          ┌───────────────┐          ┌──────────────┐          ┌──────────────┐
│              │          │               │          │              │          │              │
│    用户      │          │    前端应用   │          │   后端服务   │          │    数据库    │
│              │          │               │          │              │          │              │
└──────┬───────┘          └───────┬───────┘          └──────┬───────┘          └──────┬───────┘
       │                          │                          │                          │
       │    1.访问应用            │                          │                          │
       │ ─────────────────────────>                          │                          │
       │                          │                          │                          │
       │                          │   2.检测用户语言设置     │                          │
       │                          │ ──────────────────┐      │                          │
       │                          │                   │      │                          │
       │                          │ <────────────────┘       │                          │
       │                          │                          │                          │
       │                          │   3.加载对应语言包       │                          │
       │                          │ ──────────────────┐      │                          │
       │                          │                   │      │                          │
       │                          │ <────────────────┘       │                          │
       │                          │                          │                          │
       │                          │   4.渲染初始界面         │                          │
       │                          │ ──────────────────┐      │                          │
       │                          │                   │      │                          │
       │                          │ <────────────────┘       │                          │
       │                          │                          │                          │
       │    5.查看界面            │                          │                          │
       │ <─────────────────────────                          │                          │
       │                          │                          │                          │
       │    6.切换语言            │                          │                          │
       │ ─────────────────────────>                          │                          │
       │                          │                          │                          │
       │                          │   7.切换本地语言设置     │                          │
       │                          │ ──────────────────┐      │                          │
       │                          │                   │      │                          │
       │                          │ <────────────────┘       │                          │
       │                          │                          │                          │
       │                          │   8.更新UI界面           │                          │
       │                          │ ──────────────────┐      │                          │
       │                          │                   │      │                          │
       │                          │ <────────────────┘       │                          │
       │                          │                          │                          │
       │    9.查看新语言界面      │                          │                          │
       │ <─────────────────────────                          │                          │
       │                          │                          │                          │
       │   10.请求数据            │                          │                          │
       │ ─────────────────────────>                          │                          │
       │                          │                          │                          │
       │                          │  11.请求数据(带语言标识) │                          │
       │                          │ ─────────────────────────>                          │
       │                          │                          │                          │
       │                          │                          │  12.查询多语言数据       │
       │                          │                          │ ─────────────────────────>
       │                          │                          │                          │
       │                          │                          │  13.返回指定语言数据     │
       │                          │                          │ <─────────────────────────
       │                          │                          │                          │
       │                          │                          │  14.处理数据与翻译       │
       │                          │                          │ ──────────────────┐      │
       │                          │                          │                   │      │
       │                          │                          │ <────────────────┘       │
       │                          │                          │                          │
       │                          │  15.返回多语言数据       │                          │
       │                          │ <─────────────────────────                          │
       │                          │                          │                          │
       │                          │  16.使用i18n渲染数据     │                          │
       │                          │ ──────────────────┐      │                          │
       │                          │                   │      │                          │
       │                          │ <────────────────┘       │                          │
       │                          │                          │                          │
       │   17.查看本地化内容      │                          │                          │
       │ <─────────────────────────                          │                          │
       │                          │                          │                          │
       ▼                          ▼                          ▼                          ▼

多语言系统维护与管理流程

┌──────────────────────────────────────────────────────────────────────┐
│                         多语言内容管理系统                            │
└───────────────┬───────────────────────────────────────┬───────────────┘
                │                                       │
                ▼                                       ▼
┌───────────────────────────────┐         ┌───────────────────────────────┐
│        翻译工作流管理         │         │        缺失翻译处理            │
│                               │         │                               │
│  ┌─────────────────────────┐  │         │  ┌─────────────────────────┐  │
│  │     新增文本识别        │  │         │  │     降级策略            │  │
│  │                         │  │         │  │                         │  │
│  │  扫描代码中的新文本     │  │         │  │  使用默认语言作为备选   │  │
│  │  提取需要翻译的内容     │  │         │  │  防止UI显示问题         │  │
│  └─────────────────────────┘  │         │  └─────────────────────────┘  │
│                               │         │                               │
│  ┌─────────────────────────┐  │         │  ┌─────────────────────────┐  │
│  │     翻译任务分配        │  │         │  │     自动翻译机制        │  │
│  │                         │  │         │  │                         │  │
│  │  分配给专业翻译人员     │  │         │  │  接入机器翻译API        │  │
│  │  或使用翻译服务         │  │         │  │  临时解决缺失翻译       │  │
│  └─────────────────────────┘  │         │  └─────────────────────────┘  │
│                               │         │                               │
│  ┌─────────────────────────┐  │         │  ┌─────────────────────────┐  │
│  │     翻译审核流程        │  │         │  │     翻译覆盖率报告      │  │
│  │                         │  │         │  │                         │  │
│  │  确保翻译质量           │  │         │  │  监控各语言翻译完成度   │  │
│  │  上下文一致性检查       │  │         │  │  优先补充高频使用内容   │  │
│  └─────────────────────────┘  │         │  └─────────────────────────┘  │
└───────────────────────────────┘         └───────────────────────────────┘
                │                                       │
                ▼                                       ▼
┌───────────────────────────────────────────────────────────────────────┐
│                         语言包发布与更新                              │
│                                                                       │
│  ┌─────────────────────────┐            ┌─────────────────────────┐   │
│  │     版本控制           │            │     增量更新机制        │   │
│  │                        │            │                         │   │
│  │  语言包版本管理        │            │  只更新变更的语言条目   │   │
│  │  历史翻译记录          │            │  减少更新成本           │   │
│  └─────────────────────────┘            └─────────────────────────┘   │
│                                                                       │
│  ┌─────────────────────────┐            ┌─────────────────────────┐   │
│  │     按需加载策略       │            │     语言包CDN分发       │   │
│  │                        │            │                         │   │
│  │  只加载当前使用语言    │            │  全球就近访问           │   │
│  │  减少资源占用          │            │  提高加载速度           │   │
│  └─────────────────────────┘            └─────────────────────────┘   │
└───────────────────────────────────────────────────────────────────────┘

前端实现方案

1. 安装依赖

npm install vue-i18n@next

2. 目录结构

src/
├── i18n/
│   ├── index.js          # i18n配置文件
│   ├── messages/         # 语言包目录
│   │   ├── zh-CN.js      # 中文语言包
│   │   ├── en-US.js      # 英文语言包
│   │   └── ...           # 其他语言包
│   └── dateTimeFormats/  # 日期时间格式配置
├── assets/
│   └── images/
│       ├── common/       # 通用图片
│       └── i18n/         # 国际化图片
│           ├── zh-CN/    # 中文图片
│           ├── en-US/    # 英文图片
│           └── ...       # 其他语言图片
└── utils/
    └── request.js        # 请求工具(添加语言标识)

3. 初始化 Vue I18n

// src/i18n/index.js
import {
    
     createI18n } from "vue-i18n";
import zhCN from "./messages/zh-CN";
import enUS from "./messages/en-US";

// 获取浏览器语言或本地存储中的语言设置
const getLocale = () => {
    
    
  const cachedLocale = localStorage.getItem("language");
  if (cachedLocale) return cachedLocale;

  const browserLocale = navigator.language;
  return browserLocale.includes("zh") ? "zh-CN" : "en-US";
};

const i18n = createI18n({
    
    
  legacy: false, // 使用composition API
  locale: getLocale(),
  fallbackLocale: "zh-CN",
  messages: {
    
    
    "zh-CN": zhCN,
    "en-US": enUS,
  },
  // 日期时间格式化
  datetimeFormats: {
    
    
    "zh-CN": {
    
    
      short: {
    
    
        year: "numeric",
        month: "2-digit",
        day: "2-digit",
      },
      long: {
    
    
        year: "numeric",
        month: "2-digit",
        day: "2-digit",
        hour: "2-digit",
        minute: "2-digit",
        second: "2-digit",
      },
    },
    "en-US": {
    
    
      short: {
    
    
        year: "numeric",
        month: "2-digit",
        day: "2-digit",
      },
      long: {
    
    
        year: "numeric",
        month: "2-digit",
        day: "2-digit",
        hour: "2-digit",
        minute: "2-digit",
        second: "2-digit",
        hour12: true,
      },
    },
  },
});

// 语言切换函数
export const setLocale = (locale) => {
    
    
  i18n.global.locale.value = locale;
  localStorage.setItem("language", locale);
  document.querySelector("html").setAttribute("lang", locale);
};

export default i18n;

4. 在 Vue 应用中注册

// src/main.js
import {
    
     createApp } from "vue";
import App from "./App.vue";
import i18n from "./i18n";

const app = createApp(App);
app.use(i18n);
app.mount("#app");

5. 文本国际化

语言包示例
// src/i18n/messages/zh-CN.js
export default {
    
    
  common: {
    
    
    hello: '你好,世界',
    welcome: '欢迎来到{name}',
    submit: '提交',
    cancel: '取消'
  },
  login: {
    
    
    title: '用户登录',
    username: '用户名',
    password: '密码',
    remember: '记住我',
    loginBtn: '登录'
  },
  // 针对图片的国际化配置
  images: {
    
    
    logo: '/assets/images/i18n/zh-CN/logo.png',
    banner: '/assets/images/i18n/zh-CN/banner.jpg'
  }
};

// src/i18n/messages/en-US.js
export default {
    
    
  common: {
    
    
    hello: 'Hello World',
    welcome: 'Welcome to {name}',
    submit: 'Submit',
    cancel: 'Cancel'
  },
  login: {
    
    
    title: 'User Login',
    username: 'Username',
    password: 'Password',
    remember: 'Remember me',
    loginBtn: 'Login'
  },
  // 针对图片的国际化配置
  images: {
    
    
    logo: '/assets/images/i18n/en-US/logo.png',
    banner: '/assets/images/i18n/en-US/banner.jpg'
  }
};
在组件中使用
<template>
  <div>
    <!-- 基本使用 -->
    <h1>{
   
   { $t("common.hello") }}</h1>

    <!-- 带参数的翻译 -->
    <p>{
   
   { $t("common.welcome", { name: appName }) }}</p>

    <!-- 使用组合式API -->
    <p>{
   
   { t("login.title") }}</p>

    <!-- 复数形式 -->
    <p>{
   
   { $tc("message.itemCount", itemCount) }}</p>

    <!-- 国际化的按钮 -->
    <button
      class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
    >
      {
   
   { $t("common.submit") }}
    </button>
  </div>
</template>

<script setup>
import { ref } from "vue";
import { useI18n } from "vue-i18n";

const { t, tc, d } = useI18n();
const appName = ref("MyApp");
const itemCount = ref(5);
</script>

6. 图片国际化

通过 i18n 配置图片路径
<template>
  <div>
    <!-- 使用国际化图片 -->
    <img :src="$t('images.logo')" alt="Logo" class="h-10 w-auto" />
    <img :src="$t('images.banner')" alt="Banner" class="w-full h-auto" />
  </div>
</template>

7. 接口请求头国际化

// src/utils/request.js
import axios from "axios";
import {
    
     useI18n } from "vue-i18n";

const service = axios.create({
    
    
  baseURL: import.meta.env.VITE_API_BASE_URL,
  timeout: 5000,
});

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    
    
    // 从 i18n 获取当前语言
    const currentLocale = localStorage.getItem("language") || "zh-CN";

    // 添加语言标识到请求头
    config.headers["Accept-Language"] = currentLocale;

    return config;
  },
  (error) => {
    
    
    return Promise.reject(error);
  }
);

export default service;

8. 语言切换组件

<template>
  <div class="relative">
    <button
      @click="toggleDropdown"
      class="flex items-center space-x-1 px-3 py-2 rounded hover:bg-gray-100"
    >
      <span>{
   
   { currentLangLabel }}</span>
      <span class="transform" :class="isOpen ? 'rotate-180' : ''">▼</span>
    </button>

    <div
      v-if="isOpen"
      class="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg z-10"
    >
      <div class="py-1">
        <a
          v-for="lang in languages"
          :key="lang.value"
          @click="changeLang(lang.value)"
          class="block px-4 py-2 text-gray-800 hover:bg-gray-100 cursor-pointer"
        >
          {
   
   { lang.label }}
        </a>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from "vue";
import { useI18n } from "vue-i18n";
import { setLocale } from "@/i18n";

const { locale } = useI18n();
const isOpen = ref(false);

const languages = [
  { label: "简体中文", value: "zh-CN" },
  { label: "English", value: "en-US" },
];

const currentLangLabel = computed(() => {
  const lang = languages.find((l) => l.value === locale.value);
  return lang ? lang.label : languages[0].label;
});

const toggleDropdown = () => {
  isOpen.value = !isOpen.value;
};

const changeLang = (langValue) => {
  setLocale(langValue);
  isOpen.value = false;
};
</script>

后端实现方案

1. 数据库设计

使用 JSON 字段或者关联表存储多语言文本:

// 单表方案(使用JSON字段)
products (
  id INT PRIMARY KEY,
  name_translations JSON, // {"zh-CN": "产品名称", "en-US": "Product Name"}
  description_translations JSON
)

// 关联表方案
products (
  id INT PRIMARY KEY,
  default_name VARCHAR(255),
  default_description TEXT
)

product_translations (
  id INT PRIMARY KEY,
  product_id INT FOREIGN KEY,
  locale VARCHAR(10),
  name VARCHAR(255),
  description TEXT
)

2. API 接口设计

// 接口输入
GET /api/products
Headers:
  Accept-Language: zh-CN

// 接口输出
{
  "code": 0,
  "data": [
    {
      "id": 1,
      "name": "产品名称", // 已根据请求头的语言返回对应文本
      "description": "产品描述"
    }
  ]
}

3. 后端处理流程

  1. 解析请求头中的语言标识
  2. 根据语言标识查询对应的语言数据
  3. 返回对应语言的数据给前端
// 伪代码示例
app.use((req, res, next) => {
    
    
  // 从请求头获取语言标识
  const locale = req.headers["accept-language"] || "zh-CN";

  // 保存到请求上下文中
  req.locale = locale;

  next();
});

项目配置最佳实践

  1. 代码规范:

    • 禁止硬编码文本,所有文本必须使用 i18n
    • 代码审查时检查国际化问题
  2. 自动化工具:

    • 使用工具提取代码中的文本到语言文件
    • 使用翻译服务 API 自动翻译新增文本
  3. 性能优化:

    • 按需加载语言包
    • 缓存已加载的语言包
  4. 测试策略:

    • 为每种语言编写 UI 测试
    • 确保布局在不同语言下正常显示

总结

这套多语言技术方案通过前后端协同工作,为应用提供完整的国际化支持。前端使用 Vue I18n 管理文本、图片和日期时间格式,后端通过请求头识别语言并返回相应数据。这样的架构使应用能够无缝地支持多种语言,提升全球用户体验。