# 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 ``` ### 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 ``` ### 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/)