## 项目中英文转换逻辑说明 ### 一、国际化(i18n)架构概述 本项目采用 **Vue I18n** 实现中英文双语切换,核心架构包含配置层、语言包层和组件调用层三个层次。 --- ### 二、核心文件结构 | 文件路径 | 功能说明 | |---------|---------| | `src/i18n.ts` | Vue I18n 核心配置,注册语言包 | | `src/i18n.d.ts` | TypeScript 类型定义文件 | | `src/locales/zh.json` | 中文语言包(键值对存储) | | `src/locales/en.json` | 英文语言包(与中文键结构一致) | | `src/locales/index.js` | 备用语言管理模块 | | `scripts/extract-i18n.js` | 自动提取国际化标记的脚本 | --- ### 三、中英文转换核心逻辑 #### 3.1 配置初始化 (`src/i18n.ts`) ```typescript import { createI18n } from 'vue-i18n'; import zh from './locales/zh.json'; import en from './locales/en.json'; const i18n = createI18n({ legacy: false, // 使用 Composition API 模式 locale: 'zh', // 默认语言:中文 fallbackLocale: 'en', // 回退语言:英文 messages: { zh, en }, // 语言包映射对象 }); export default i18n; ``` **关键配置说明:** - `legacy: false` - 启用 Vue 3 Composition API 兼容模式 - `locale` - 当前活跃语言标识 - `fallbackLocale` - 当某个 key 在当前语言包不存在时,使用回退语言 #### 3.2 语言包结构 语言包采用**嵌套 JSON 结构**,支持层级键路径: ```json // src/locales/zh.json { "Header": { "title": "土壤酸化智能预测专家系统", "welcome": "欢迎", "logout": "退出登录" }, "login": { "userTitle": "用户登录", "loginButton": "登录", "loginFailed": "登录失败,请检查用户名或密码" }, "validation": { "usernameRequired": "请输入账号", "passwordLength": "密码长度为 3 到 16 个字符" } } ``` #### 3.3 组件调用方式 **Vue 模板中的使用:** ```vue ``` **TypeScript 文件中的使用:** ```typescript // 在组合式函数中使用 import { useI18n } from 'vue-i18n'; const { t } = useI18n(); // 用于消息提示 ElMessage.success(t('login.loginSuccess')); // 用于动态文本 const errorMsg = t('login.loginFailed'); ``` --- ### 四、语言切换流程 #### 4.1 完整切换流程(以登录页为例) ```typescript // src/views/login/loginView.vue const toggleLanguage = async () => { // 1. 计算新语言 const newLocale = locale.value === "zh" ? "en" : "zh"; // 2. 更新 Vue I18n locale(触发视图自动更新) locale.value = newLocale; // 3. 持久化到 localStorage(刷新页面保持语言设置) localStorage.setItem("lang", newLocale); // 4. 可选:同步到后端(保存用户语言偏好) try { await changeLanguageAPI({ language: newLocale, userId: store.userInfo?.userId, timestamp: Date.now(), }); } catch (error) { console.error("语言切换同步失败:", error); } }; ``` #### 4.2 初始化时的语言恢复 在应用启动时,从 localStorage 读取上次保存的语言: ```typescript // src/main.ts const savedLang = localStorage.getItem('lang') || 'zh'; const i18n = createI18n({ locale: savedLang, // ... 其他配置 }); ``` --- ### 五、国际化标记提取脚本 #### 5.1 脚本位置和功能 **脚本文件:** `scripts/extract-i18n.js` **核心功能:** - 自动扫描 `.vue` 和 `.ts` 文件 - 识别特定标记格式的中文文本 - 自动生成/更新语言包文件 #### 5.2 使用方法 ```bash # 扫描整个 src 目录(默认) node scripts/extract-i18n.js # 扫描指定目录 node scripts/extract-i18n.js src/views/User # 扫描单个文件 node scripts/extract-i18n.js src/components/layout/AppLayout.vue ``` #### 5.3 提取标记格式 在 Vue/TS 文件中使用以下格式标记需要国际化的文本: ```vue 中文文本内容 ``` **示例:** ```vue 土壤酸化智能预测专家系统 用户登录 数据管理 ``` #### 5.4 脚本处理流程 ``` 1. 解析命令行参数 → 确定扫描路径 2. 读取已有语言包 → 保留历史翻译 3. 递归扫描文件 → 收集 .vue/.ts 文件 4. 正则匹配标记 → 提取键名和中文文本 5. 构建嵌套对象 → 处理键路径(如 Menu.subMenu.item) 6. 写入语言包 → 更新 zh.json 和 en.json ``` #### 5.5 脚本核心代码解析 **标记匹配正则:** ```javascript const regex = /([\u4e00-\u9fa5\w\s,.,。;;!!??::()()]+?)(?=\r?\n|['"<]|$)/g; ``` **嵌套键设置函数:** ```javascript function setNestedValue(obj, keyPath, value) { const keys = keyPath.split('.'); let current = obj; for (let i = 0; i < keys.length - 1; i++) { const key = keys[i]; if (typeof current[key] === 'string') { console.warn(`键名冲突:"${key}" 已作为字符串存在`); return; } if (!current[key] || typeof current[key] !== 'object') { current[key] = {}; } current = current[key]; } const lastKey = keys[keys.length - 1]; if (current[lastKey] === undefined) { current[lastKey] = value; } } ``` --- ### 六、语言包维护规范 | 规范项 | 说明 | |-------|------| | **键命名** | 使用 `模块名.子模块.键名` 格式,如 `Menu.dataManagement` | | **结构对齐** | 中英文语言包必须保持**完全相同的键结构** | | **值处理** | 中文包存储中文原文,英文包存储对应英文翻译 | | **新增翻译** | 同时在 `zh.json` 和 `en.json` 中添加键值对 | | **标记规范** | 使用 `` 标记便于脚本提取 | | **避免硬编码** | 所有用户可见文本必须通过 `t()` 函数获取 | --- ### 七、现有翻译覆盖范围 | 模块 | 说明 | |-----|------| | **Header** | 顶部导航栏文本 | | **login/register/logout** | 登录、注册、退出相关 | | **Menu** | 侧边栏菜单项 | | **validation** | 表单验证提示 | | **AcidModelMap** | 酸化模型地图相关 | | **PhPrediction** | pH 预测模型相关 | | **Calculation** | 计算模块相关 | | **DetectionStatistics** | 检测统计相关 | | **SoilCdStatistics** | 土壤镉统计相关 | | **LandCultivatedStatistics** | 耕地统计相关 | --- ### 八、Element Plus 组件国际化 Element Plus 组件默认使用中文,如需支持英文需额外配置: ```typescript // src/main.ts import ElementPlus from 'element-plus'; import zhCn from 'element-plus/es/locale/lang/zh-cn'; import en from 'element-plus/es/locale/lang/en'; // 根据当前语言动态切换 Element Plus 语言 app.use(ElementPlus, { locale: locale.value === 'zh' ? zhCn : en, }); ``` --- ### 九、扩展说明 #### 9.1 添加新翻译流程 1. **标记文本**:在 Vue/TS 文件中添加 `` 标记 2. **运行脚本**:执行 `node scripts/extract-i18n.js` 提取标记 3. **翻译英文**:在 `en.json` 中填写对应英文翻译 4. **使用翻译**:在组件中使用 `t('键名')` 获取文本 #### 9.2 语言切换事件通知 通过自定义事件通知其他组件语言变化: ```typescript // 触发语言切换事件 window.dispatchEvent(new CustomEvent('languageChanged', { detail: { locale: locale.value } })); // 监听语言切换事件 window.addEventListener('languageChanged', (e) => { console.log('语言已切换为:', e.detail.locale); }); ```