# uni-i18n
**Repository Path**: penghg/uni-i18n
## Basic Information
- **Project Name**: uni-i18n
- **Description**: 主要是针对uniapp国际化使用的总结与示例
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2023-12-19
- **Last Updated**: 2024-08-05
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
### 前言
实际上uni官网关于国际化应用的文档写的已经很详细了,因近期公司项目应用到国际化,在使用的过程中,也遇到了一些问题,特梳理了记录下~
### 国际化配置
main.js引入并初始化VueI18n
```javascript
import App from './App'
import Vue from 'vue'
import VueI18n from 'vue-i18n'
// 多语言
import {
langMessage
} from '@/locale/index'
let i18nConfig = {
locale: uni.getLocale() || systemInfo.language || 'zh-Hant',
fallbackLocale: "zh-Hant",
silentTranslationWarn: true, // 去除国际化警告
messages: langMessage()
}
Vue.use(VueI18n)
const i18n = new VueI18n(i18nConfig)
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
i18n,
...App
})
app.$mount()
```
细心的同学肯定会发现,为啥这边引入多语言内容的方式与[官网示例](https://uniapp.dcloud.net.cn/tutorial/i18n.html)有点不同。
官网是直接引用多语言的json文件,考虑到json文件不好进行模块拆分,把项目中所有的多语言都配置在同一个文件,会导致后期维护麻烦,本项目示例中按模块进行拆分。具体的可查看`@/common/i18n/`(业务中使用的国际化语言包)。
当然,别忘了把数据格式转换成uniapp支持的格式,在main.js引用前,数据进行转换,原码路径`@/locale/index`
```javascript
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
import {
messages
} from '@/common/i18n/index.js'
/**
* 多语言数据格式转换
* @param {Object} messages
* @param {Object} key
*/
function dataFormatting(messages, key) {
let map = {};
function objParse(holder, key, lastKey) {
if (holder && typeof holder === "object") {
if (key !== '') {
lastKey += key + "."
}
// 对象遍历
for (let k in holder) {
objParse(holder[k], k, lastKey);
}
} else {
lastKey += key
map[lastKey] = holder
}
}
objParse(messages[key], "", "")
return map;
}
let i18nMessage = {}
export function langMessage() {
// 缓存,防止多次转化
if (Object.keys(i18nMessage).length === 0) {
i18nMessage = {
'en': {
...en,
...dataFormatting(messages, "en")
},
'zh-Hans': {
...zhHans,
...dataFormatting(messages, "zh-Hans")
},
'zh-Hant': {
...zhHant,
...dataFormatting(messages, "zh-Hant")
}
}
// compareDiff(i18nMessage)
}
return i18nMessage
}
```
在`@/locale/index`中,提供了各语言包之间的比对,方便快速定位哪些国际化key漏配。
### 基本用法(vue或js)
在vue或js中,使用与web方案很相近,页面模板中使用 `$t()` 获取,并传递国际文件中定义的key,js中使用 `this.$t('')`,具体使用示例见`index.vue`
```vue
{{$t('index.title')}}
{{$t('index.desc')}}
```
### nvue页面国际化
nvue目前的国际化方案需要在每个页面单独引入uni-i18n,官网说后期会抹平差异,具体时间待定。
具体实现见nvue页面,考虑到项目可能会有多个nvue页面,把nvue页面需要引入的uni-i18n提成一个js,方便公用。
```javascript
// @/common/util/i18n.js
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import {
langMessage
} from '@/locale/index'
const {
t
} = initVueI18n(langMessage())
export const i18n = {
t
}
```
- nvue页面国际化示例
```vue
{{i18n.t('nvue.title')}}
{{i18n.t('nvue.desc')}}
{{i18n.t('nvue.text')}}
```
### pages.json国际化
pages.json不属于vue页面,其中的原生tabbar和原生导航栏里也有文字内容。这部分国际化要特别注意,只能写在项目根目录的locale目录下配置语言json文件,我尝试过写在`common/i18n`,发现并没有生效,细想也能理解,因为这些内容的国际化在项目加载之前就生成了
```json
// pages.json
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "%navigationBarTitleText.index%" // locale目录下 语言地区代码.json 文件中定义的 key,使用 %% 占位
}
},
{
"path" : "pages/nvue/nvue",
"style" :
{
"navigationBarTitleText" : "%navigationBarTitleText.nvue%",
"enablePullDownRefresh" : false
}
},
{
"path" : "pages/setting/setting",
"style" :
{
"navigationBarTitleText" : "%navigationBarTitleText.setting%",
"enablePullDownRefresh" : false
}
}
],
"tabBar": {
"borderStyle": "white",
"color": "#999999",
"selectedColor": "#4bb1ff",
"backgroundColor": "#FFFFFF",
"list": [{
"text": "%tabbar.index%",
"pagePath": "pages/index/index",
"iconPath": "/static/images/tabbar/index.png",
"selectedIconPath": "/static/images/tabbar/indexSelect.png"
},
{
"text": "%tabbar.nvue%",
"pagePath": "pages/nvue/nvue",
"iconPath": "/static/images/tabbar/nvue.png",
"selectedIconPath": "/static/images/tabbar/nvueSelect.png"
},
{
"text": "%tabbar.setting%",
"pagePath": "pages/setting/setting",
"iconPath": "/static/images/tabbar/setting.png",
"selectedIconPath": "/static/images/tabbar/settingSelect.png"
}
]
}
}
```
pages.json 支持以下属性配置国际化信息
> navigationBarTitleText
>titleNView->titleText
>titleNView->searchInput->placeholder
>tabBar->list->text
>注:小程序下不支持这种国际化方案,也可以使用设置tabbar和navigationbar的API来设置文字。或者废弃原生tabbar和navigationbar,使用自定义方式。
### 应用名称及iOS隐私提示语的国际化
```json
"locales" : {
"en" : {
// 英文
"name" : "uni-i18n", // 应用名称
"ios" : {
"privacyDescription" : {
"NSPhotoLibraryUsageDescription" : "Get the user album content permission to manually select and upload photos from the album when changing avatar information. Is it allowed to read album content",
"NSCameraUsageDescription" : "Get the user camera permission to take photos and upload photos when changing avatar information. Is it allowed to use the camera"
}
}
},
"zh" : {
// 中文(简体)
"name" : "uni-国际化",
"ios" : {
"privacyDescription" : {
//iOS平台隐私访问描述信息
"NSPhotoLibraryUsageDescription" : "获取用户相册内容权限,用于更改头像信息时手动选择上传相册内的照片,是否允许读取相册内容",
"NSCameraUsageDescription" : "获取用户摄像头权限,用于更改头像信息时拍照上传照片,是否允许使用摄像头"
}
}
},
"zh-TW" : {
// 中文(繁体)
"name" : "uni-國際化",
"ios" : {
"privacyDescription" : {
//iOS平台隐私访问描述信息
"NSPhotoLibraryUsageDescription" : "獲取用戶相册內容許可權,用於更改頭像資訊時手動選擇上傳相册內的照片,是否允許讀取相册內容",
"NSCameraUsageDescription" : "獲取用戶監視器許可權,用於更改頭像資訊時拍照上傳照片,是否允許使用監視器"
}
}
}
}
```
详细用法见[应用云端打包国际化处理](https://ask.dcloud.net.cn/article/35860)
应用名国际时,慎用以下方式,我遇到在本地调试时,经常提示异常。[异常现象](https://ask.dcloud.net.cn/question/154678)
和 `pages.json `一致,在项目根目录增加`locale/uni-app.语言地区代码.json`文件,然后在 `manifest.json` 中使用`%%`占位
```json
{
"name" : "%app.name%",
}
```
### 遇到问题
- 如何将语言包按模块拆分,方便后期维护
官网是直接引用多语言的json文件,考虑到json文件不好进行模块拆分,把项目中所有的多语言都配置在同一个文件,会导致后期维护麻烦,本项目示例中按模块进行拆分。具体的可查看`@/common/i18n/`(业务中使用的国际化语言包)。
- nvue页面国际化问题
考虑到项目可能会有多个nvue页面,把nvue页面需要引入的uni-i18n提成一个js,方便公用,后续调用与vue页面类似
- mainfest.json应用名称国际化后,自定义基座运行后提示异常
按照官网提示的示例,在项目根目录增加 locale/uni-app.语言地区代码.json 文件,然后在 manifest.json 中使用 %% 占位,自定义基座运行时,会提示如下异常,正式包打包应用名又能正常显示。
```bash
14:22:33.184 应用【%app.name%】已启动
14:22:34.197 error
14:22:34.197 请求的页面无法打开:file:///storage/emulated/0/Android/data/uni.UNIC0CCBD4/apps/__UNI__C0CCBD4/www/__uniappview.html at file:///android_asset/data/dcloud_error.html:41
```
具体的解决方案参考`应用名称及iOS隐私提示语的国际化`
当然,看再多的文档,不如亲身去体验~赶紧下载试试,如果有什么建议,欢迎指导交流~
### 原码地址
您可以前往gite下载,[uni-i18n](https://gitee.com/penghg/uni-i18n)
也可以在插件市场下载[uniapp国际化应用与示例](https://ext.dcloud.net.cn/plugin?id=15983)
### 特别感谢
本项目使用的UI框架,界面风格大气,上手简单 [uView](https://www.uviewui.com/)