|
|
@@ -1,485 +0,0 @@
|
|
|
-# 国际化完整指南
|
|
|
-
|
|
|
-## 📦 已完成的功能
|
|
|
-
|
|
|
-✅ vue-i18n 集成
|
|
|
-✅ 模块化语言包管理
|
|
|
-✅ 中英文双语支持
|
|
|
-✅ 语言切换功能
|
|
|
-✅ 持久化存储
|
|
|
-✅ Pinia 状态管理
|
|
|
-✅ 可复用组件
|
|
|
-✅ 完整文档
|
|
|
-
|
|
|
-## 📁 项目结构
|
|
|
-
|
|
|
-```
|
|
|
-intelligent-etmf-system-applet/
|
|
|
-├── i18n/ # i18n 配置
|
|
|
-│ ├── index.js # i18n 初始化
|
|
|
-│ └── README.md # 使用文档
|
|
|
-├── locales/ # 语言包(按模块分组)
|
|
|
-│ ├── common/ # 通用模块
|
|
|
-│ │ ├── zh_CN.js # 中文翻译
|
|
|
-│ │ └── en_US.js # 英文翻译
|
|
|
-│ ├── pages/ # 页面模块
|
|
|
-│ │ └── home/ # 首页
|
|
|
-│ │ ├── zh_CN.js # 中文翻译
|
|
|
-│ │ └── en_US.js # 英文翻译
|
|
|
-│ ├── components/ # 组件模块
|
|
|
-│ │ └── languageSwitcher/ # 语言切换组件
|
|
|
-│ │ ├── zh_CN.js # 中文翻译
|
|
|
-│ │ └── en_US.js # 英文翻译
|
|
|
-│ ├── index.js # 语言包总导出
|
|
|
-│ ├── README.md # 语言包管理文档
|
|
|
-│ ├── STRUCTURE.md # 目录结构说明
|
|
|
-│ └── COMPONENT_I18N.md # 组件国际化指南
|
|
|
-├── store/ # 状态管理
|
|
|
-│ └── locale.js # 语言切换 store
|
|
|
-├── utils/ # 工具函数
|
|
|
-│ └── i18n.js # i18n 工具函数
|
|
|
-├── components/ # 组件
|
|
|
-│ └── LanguageSwitcher/ # 语言切换组件
|
|
|
-│ └── index.vue
|
|
|
-└── main.js # 已集成 i18n
|
|
|
-```
|
|
|
-
|
|
|
-## 🚀 快速开始
|
|
|
-
|
|
|
-### 1. 在页面中使用国际化
|
|
|
-
|
|
|
-```vue
|
|
|
-<template>
|
|
|
- <view>
|
|
|
- <!-- 基础用法 -->
|
|
|
- <text>{{ t('home.title') }}</text>
|
|
|
-
|
|
|
- <!-- 嵌套键 -->
|
|
|
- <text>{{ t('common.button.submit') }}</text>
|
|
|
-
|
|
|
- <!-- 带参数 -->
|
|
|
- <text>{{ t('common.greeting', { name: userName }) }}</text>
|
|
|
- </view>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup>
|
|
|
-import { useI18n } from 'vue-i18n'
|
|
|
-
|
|
|
-const { t } = useI18n()
|
|
|
-const userName = '张三'
|
|
|
-</script>
|
|
|
-```
|
|
|
-
|
|
|
-### 2. 在组件中使用国际化
|
|
|
-
|
|
|
-```vue
|
|
|
-<template>
|
|
|
- <view class="user-card">
|
|
|
- <!-- 使用组件专属翻译 -->
|
|
|
- <text>{{ t('components.userCard.title') }}</text>
|
|
|
-
|
|
|
- <!-- 使用通用翻译 -->
|
|
|
- <button>{{ t('common.button.confirm') }}</button>
|
|
|
-
|
|
|
- <!-- 动态键 -->
|
|
|
- <text>{{ t(`components.userCard.status.${user.status}`) }}</text>
|
|
|
- </view>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup>
|
|
|
-import { useI18n } from 'vue-i18n'
|
|
|
-
|
|
|
-const { t } = useI18n()
|
|
|
-const props = defineProps({
|
|
|
- user: Object
|
|
|
-})
|
|
|
-</script>
|
|
|
-```
|
|
|
-
|
|
|
-### 3. 使用语言切换组件
|
|
|
-
|
|
|
-```vue
|
|
|
-<template>
|
|
|
- <view class="header">
|
|
|
- <!-- 方式1:使用封装的组件 -->
|
|
|
- <LanguageSwitcher />
|
|
|
-
|
|
|
- <!-- 方式2:自定义切换逻辑 -->
|
|
|
- <button @click="changeLanguage">切换语言</button>
|
|
|
- </view>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup>
|
|
|
-import { useLocaleStore } from '@/store/locale'
|
|
|
-import LanguageSwitcher from '@/components/LanguageSwitcher/index.vue'
|
|
|
-
|
|
|
-const localeStore = useLocaleStore()
|
|
|
-
|
|
|
-const changeLanguage = () => {
|
|
|
- // 切换到下一个语言
|
|
|
- localeStore.toggleLocale()
|
|
|
-
|
|
|
- // 或切换到指定语言
|
|
|
- // localeStore.setLocale('en-US')
|
|
|
-}
|
|
|
-</script>
|
|
|
-```
|
|
|
-
|
|
|
-### 4. 在 JS 中使用(非组件环境)
|
|
|
-
|
|
|
-```javascript
|
|
|
-import { t } from '@/utils/i18n'
|
|
|
-
|
|
|
-// 在 API 请求中使用
|
|
|
-const showError = () => {
|
|
|
- uni.showToast({
|
|
|
- title: t('common.message.error'),
|
|
|
- icon: 'none'
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-// 在工具函数中使用
|
|
|
-const formatStatus = (status) => {
|
|
|
- return t(`order.status.${status}`)
|
|
|
-}
|
|
|
-```
|
|
|
-
|
|
|
-## 🎨 为组件添加国际化
|
|
|
-
|
|
|
-### 为什么要为组件创建专门的翻译?
|
|
|
-
|
|
|
-- 组件有特定的业务术语
|
|
|
-- 组件需要在多处复用
|
|
|
-- 便于独立维护和版本管理
|
|
|
-
|
|
|
-### 快速示例
|
|
|
-
|
|
|
-创建 UserCard 组件的翻译:
|
|
|
-
|
|
|
-1. 创建翻译文件:`locales/components/userCard/zh_CN.js` 和 `en_US.js`
|
|
|
-2. 在 `locales/index.js` 中注册到 `components` 下
|
|
|
-3. 在组件中使用:`t('components.userCard.title')`
|
|
|
-
|
|
|
-**详细指南**:请查看 [组件国际化指南](./locales/COMPONENT_I18N.md)
|
|
|
-
|
|
|
-## 📝 添加新的翻译模块
|
|
|
-
|
|
|
-### 页面模块示例
|
|
|
-
|
|
|
-在对应目录下创建语言文件。例如创建产品管理页面模块:
|
|
|
-
|
|
|
-创建 `locales/pages/product/zh_CN.js`:
|
|
|
-```javascript
|
|
|
-export default {
|
|
|
- title: '产品管理',
|
|
|
- list: {
|
|
|
- title: '产品列表',
|
|
|
- empty: '暂无产品'
|
|
|
- },
|
|
|
- detail: {
|
|
|
- name: '产品名称',
|
|
|
- price: '价格',
|
|
|
- stock: '库存'
|
|
|
- },
|
|
|
- action: {
|
|
|
- add: '添加产品',
|
|
|
- edit: '编辑',
|
|
|
- delete: '删除'
|
|
|
- }
|
|
|
-}
|
|
|
-```
|
|
|
-
|
|
|
-创建 `locales/pages/product/en_US.js`:
|
|
|
-```javascript
|
|
|
-export default {
|
|
|
- title: 'Product Management',
|
|
|
- list: {
|
|
|
- title: 'Product List',
|
|
|
- empty: 'No products'
|
|
|
- },
|
|
|
- detail: {
|
|
|
- name: 'Product Name',
|
|
|
- price: 'Price',
|
|
|
- stock: 'Stock'
|
|
|
- },
|
|
|
- action: {
|
|
|
- add: 'Add Product',
|
|
|
- edit: 'Edit',
|
|
|
- delete: 'Delete'
|
|
|
- }
|
|
|
-}
|
|
|
-```
|
|
|
-
|
|
|
-### 步骤 2:注册模块
|
|
|
-
|
|
|
-在 `locales/index.js` 中导入新模块:
|
|
|
-```javascript
|
|
|
-// 导入通用模块
|
|
|
-import commonZhCN from './common/zh_CN'
|
|
|
-import commonEnUS from './common/en_US'
|
|
|
-
|
|
|
-// 导入页面模块
|
|
|
-import homeZhCN from './pages/home/zh_CN'
|
|
|
-import homeEnUS from './pages/home/en_US'
|
|
|
-import productZhCN from './pages/product/zh_CN' // 新增
|
|
|
-import productEnUS from './pages/product/en_US' // 新增
|
|
|
-
|
|
|
-// 导入组件模块
|
|
|
-import languageSwitcherZhCN from './components/languageSwitcher/zh_CN'
|
|
|
-import languageSwitcherEnUS from './components/languageSwitcher/en_US'
|
|
|
-
|
|
|
-export const messages = {
|
|
|
- 'zh-CN': {
|
|
|
- common: commonZhCN,
|
|
|
- home: homeZhCN,
|
|
|
- product: productZhCN, // 新增
|
|
|
- components: {
|
|
|
- languageSwitcher: languageSwitcherZhCN
|
|
|
- }
|
|
|
- },
|
|
|
- 'en-US': {
|
|
|
- common: commonEnUS,
|
|
|
- home: homeEnUS,
|
|
|
- product: productEnUS, // 新增
|
|
|
- components: {
|
|
|
- languageSwitcher: languageSwitcherEnUS
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-```
|
|
|
-
|
|
|
-**注意**:
|
|
|
-- 页面模块直接注册在第一层
|
|
|
-- 组件模块注册在 `components` 对象下
|
|
|
-
|
|
|
-### 步骤 3:使用新模块
|
|
|
-
|
|
|
-```vue
|
|
|
-<template>
|
|
|
- <view>
|
|
|
- <text>{{ t('product.title') }}</text>
|
|
|
- <text>{{ t('product.detail.name') }}</text>
|
|
|
- </view>
|
|
|
-</template>
|
|
|
-```
|
|
|
-
|
|
|
-## 🌍 添加新语言
|
|
|
-
|
|
|
-### 步骤 1:创建语言文件
|
|
|
-
|
|
|
-为每个现有模块创建新语言的翻译文件:
|
|
|
-
|
|
|
-```
|
|
|
-locales/
|
|
|
- ├── common/
|
|
|
- │ ├── zh_CN.js
|
|
|
- │ ├── en_US.js
|
|
|
- │ └── ja_JP.js # 新增日文
|
|
|
- └── pages/
|
|
|
- └── home/
|
|
|
- ├── zh_CN.js
|
|
|
- ├── en_US.js
|
|
|
- └── ja_JP.js # 新增日文
|
|
|
-```
|
|
|
-
|
|
|
-### 步骤 2:更新配置
|
|
|
-
|
|
|
-在 `locales/index.js` 中:
|
|
|
-```javascript
|
|
|
-import commonZhCN from './common/zh_CN'
|
|
|
-import commonEnUS from './common/en_US'
|
|
|
-import commonJaJP from './common/ja_JP' // 新增
|
|
|
-
|
|
|
-import homeZhCN from './pages/home/zh_CN'
|
|
|
-import homeEnUS from './pages/home/en_US'
|
|
|
-import homeJaJP from './pages/home/ja_JP' // 新增
|
|
|
-
|
|
|
-export const messages = {
|
|
|
- 'zh-CN': {
|
|
|
- common: commonZhCN,
|
|
|
- home: homeZhCN
|
|
|
- },
|
|
|
- 'en-US': {
|
|
|
- common: commonEnUS,
|
|
|
- home: homeEnUS
|
|
|
- },
|
|
|
- 'ja-JP': { // 新增
|
|
|
- common: commonJaJP,
|
|
|
- home: homeJaJP
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-export const localeList = [
|
|
|
- { label: '简体中文', value: 'zh-CN' },
|
|
|
- { label: 'English', value: 'en-US' },
|
|
|
- { label: '日本語', value: 'ja-JP' } // 新增
|
|
|
-]
|
|
|
-```
|
|
|
-
|
|
|
-## 💡 最佳实践
|
|
|
-
|
|
|
-### 1. 模块划分原则
|
|
|
-
|
|
|
-- **common/**:通用文本(按钮、消息、错误提示等),所有语言文件都在 `locales/common/` 下
|
|
|
-- **pages/**:页面模块,每个页面一个子目录(如 `pages/home/`、`pages/user/`),每个子目录下包含各语言版本
|
|
|
-- **其他业务模块**:可根据需要创建其他模块目录(如 `api/`、`components/` 等)
|
|
|
-
|
|
|
-**优势**:
|
|
|
-- 同一功能的不同语言翻译在同一目录下,便于对比和维护
|
|
|
-- 添加新语言只需在每个模块目录下添加新的语言文件
|
|
|
-- 模块划分清晰,职责明确
|
|
|
-
|
|
|
-### 2. 命名规范
|
|
|
-
|
|
|
-```javascript
|
|
|
-// ✅ 推荐:清晰的层级结构
|
|
|
-{
|
|
|
- user: {
|
|
|
- profile: {
|
|
|
- title: '个人资料',
|
|
|
- field: {
|
|
|
- name: '姓名',
|
|
|
- email: '邮箱'
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// ❌ 不推荐:扁平结构
|
|
|
-{
|
|
|
- userProfileTitle: '个人资料',
|
|
|
- userProfileFieldName: '姓名'
|
|
|
-}
|
|
|
-```
|
|
|
-
|
|
|
-### 3. 参数化文本
|
|
|
-
|
|
|
-```javascript
|
|
|
-// 定义
|
|
|
-{
|
|
|
- welcome: '欢迎,{name}!',
|
|
|
- itemCount: '共 {count} 项'
|
|
|
-}
|
|
|
-
|
|
|
-// 使用
|
|
|
-t('common.welcome', { name: '张三' })
|
|
|
-t('common.itemCount', { count: 10 })
|
|
|
-```
|
|
|
-
|
|
|
-### 4. 保持同步
|
|
|
-
|
|
|
-确保同一模块下所有语言文件的翻译键完全一致:
|
|
|
-```javascript
|
|
|
-// ✅ 正确:locales/pages/user/zh_CN.js 和 locales/pages/user/en_US.js 键名相同
|
|
|
-// zh_CN.js
|
|
|
-{ user: { name: '姓名' } }
|
|
|
-
|
|
|
-// en_US.js
|
|
|
-{ user: { name: 'Name' } }
|
|
|
-
|
|
|
-// ❌ 错误:键名不一致
|
|
|
-// zh_CN.js
|
|
|
-{ user: { name: '姓名' } }
|
|
|
-
|
|
|
-// en_US.js
|
|
|
-{ user: { userName: 'Name' } } // 键名不同!
|
|
|
-```
|
|
|
-
|
|
|
-**提示**:建议同时打开同一模块的不同语言文件进行对比编辑
|
|
|
-
|
|
|
-## 🔧 API 参考
|
|
|
-
|
|
|
-### useLocaleStore
|
|
|
-
|
|
|
-```javascript
|
|
|
-const localeStore = useLocaleStore()
|
|
|
-
|
|
|
-// 状态
|
|
|
-localeStore.currentLocale // 当前语言:'zh-CN' | 'en-US'
|
|
|
-localeStore.availableLocales // 可用语言列表
|
|
|
-
|
|
|
-// 方法
|
|
|
-localeStore.setLocale('en-US') // 切换到指定语言
|
|
|
-localeStore.toggleLocale() // 切换到下一个语言
|
|
|
-localeStore.getCurrentLocaleName() // 获取当前语言显示名称
|
|
|
-```
|
|
|
-
|
|
|
-### useI18n
|
|
|
-
|
|
|
-```javascript
|
|
|
-const { t, locale, te } = useI18n()
|
|
|
-
|
|
|
-t('home.title') // 翻译文本
|
|
|
-t('common.greeting', { name: 'John' }) // 带参数翻译
|
|
|
-locale.value // 当前语言
|
|
|
-te('home.title') // 检查键是否存在
|
|
|
-```
|
|
|
-
|
|
|
-### 工具函数
|
|
|
-
|
|
|
-```javascript
|
|
|
-import { t, getLocale, setLocale, hasKey } from '@/utils/i18n'
|
|
|
-
|
|
|
-t('home.title') // 翻译文本
|
|
|
-getLocale() // 获取当前语言
|
|
|
-setLocale('en-US') // 设置语言
|
|
|
-hasKey('home.title') // 检查键是否存在
|
|
|
-```
|
|
|
-
|
|
|
-## 🐛 常见问题
|
|
|
-
|
|
|
-### 问题 1:翻译不生效
|
|
|
-
|
|
|
-**原因**:翻译键不存在或拼写错误
|
|
|
-
|
|
|
-**解决**:
|
|
|
-1. 检查翻译键是否正确
|
|
|
-2. 确认模块是否正确导入
|
|
|
-3. 使用浏览器开发工具查看警告信息
|
|
|
-
|
|
|
-### 问题 2:语言切换后页面未更新
|
|
|
-
|
|
|
-**原因**:使用了非响应式的方式获取翻译
|
|
|
-
|
|
|
-**解决**:
|
|
|
-```javascript
|
|
|
-// ❌ 错误:在 setup 外部获取
|
|
|
-const title = t('home.title')
|
|
|
-
|
|
|
-// ✅ 正确:在模板中使用或使用 computed
|
|
|
-{{ t('home.title') }}
|
|
|
-// 或
|
|
|
-const title = computed(() => t('home.title'))
|
|
|
-```
|
|
|
-
|
|
|
-### 问题 3:小程序环境报错
|
|
|
-
|
|
|
-**原因**:i18n 配置不兼容
|
|
|
-
|
|
|
-**解决**:确保使用以下配置
|
|
|
-```javascript
|
|
|
-createI18n({
|
|
|
- legacy: false, // 必须:使用 Composition API
|
|
|
- globalInjection: true, // 必须:全局注入
|
|
|
- // ...
|
|
|
-})
|
|
|
-```
|
|
|
-
|
|
|
-## 📚 相关文档
|
|
|
-
|
|
|
-- [i18n 使用指南](./i18n/README.md)
|
|
|
-- [语言包管理](./locales/README.md)
|
|
|
-- [目录结构说明](./locales/STRUCTURE.md)
|
|
|
-- [组件国际化指南](./locales/COMPONENT_I18N.md)
|
|
|
-- [Vue I18n 官方文档](https://vue-i18n.intlify.dev/)
|
|
|
-
|
|
|
-## 🎯 TODO
|
|
|
-
|
|
|
-- [ ] 添加更多语言支持(日语、韩语等)
|
|
|
-- [ ] 实现语言包懒加载优化
|
|
|
-- [ ] 添加翻译缺失检测工具
|
|
|
-- [ ] 集成在线翻译服务
|
|
|
-
|
|
|
-## 📞 联系方式
|
|
|
-
|
|
|
-如有问题或建议,请联系项目维护者。
|