更新记录
102(2023-12-20) 下载此版本
1、使用文档更新
101(2023-12-20) 下载此版本
1、程序优化 2、使用说明优化
100(2023-12-20) 下载此版本
1、uniapp国际化应用与示例
查看更多平台兼容性
Vue2 | Vue3 |
---|---|
√ | × |
App | 快应用 | 微信小程序 | 支付宝小程序 | 百度小程序 | 字节小程序 | QQ小程序 |
---|---|---|---|---|---|---|
HBuilderX 3.98 app-vue app-nvue | × | × | × | × | × | × |
钉钉小程序 | 快手小程序 | 飞书小程序 | 京东小程序 |
---|---|---|---|
× | × | × | × |
H5-Safari | Android Browser | 微信浏览器(Android) | QQ浏览器(Android) | Chrome | IE | Edge | Firefox | PC-Safari |
---|---|---|---|---|---|---|---|---|
√ | √ | √ | √ | √ | √ | √ | √ | √ |
前言
实际上uni官网关于国际化应用的文档写的已经很详细了,因近期公司项目应用到国际化,在使用的过程中,也遇到了一些问题,特梳理了记录下~
国际化配置
main.js引入并初始化VueI18n
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()
细心的同学肯定会发现,为啥这边引入多语言内容的方式与官网示例有点不同。
官网是直接引用多语言的json文件,考虑到json文件不好进行模块拆分,把项目中所有的多语言都配置在同一个文件,会导致后期维护麻烦,本项目示例中按模块进行拆分。具体的可查看@/common/i18n/
(业务中使用的国际化语言包)。
当然,别忘了把数据格式转换成uniapp支持的格式,在main.js引用前,数据进行转换,原码路径@/locale/index
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
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="vue">
<view class="vue__title">{{$t('index.title')}}</view>
<view class="vue__desc">{{$t('index.desc')}}</view>
<u--text mode="link" :text="$t('index.link')"
href="https://uniapp.dcloud.net.cn/tutorial/i18n.html"></u--text>
</view>
<u-button :text="$t('index.button.clickMe')" type="success" @click="tip"></u-button>
</view>
</template>
<script>
export default {
methods: {
tip(){
uni.showToast({
icon: 'none',
title: this.$t('index.tip.msg'),
duration: 3000
});
}
}
}
</script>
nvue页面国际化
nvue目前的国际化方案需要在每个页面单独引入uni-i18n,官网说后期会抹平差异,具体时间待定。
具体实现见nvue页面,考虑到项目可能会有多个nvue页面,把nvue页面需要引入的uni-i18n提成一个js,方便公用。
// @/common/util/i18n.js
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import {
langMessage
} from '@/locale/index'
const {
t
} = initVueI18n(langMessage())
export const i18n = {
t
}
- nvue页面国际化示例
<template>
<view class="nvue">
<text class="nvue__title">{{i18n.t('nvue.title')}}</text>
<text class="nvue__desc">{{i18n.t('nvue.desc')}}</text>
<text class="nvue__text">{{i18n.t('nvue.text')}}</text>
<u--text mode="link" :text="i18n.t('nvue.link')" href="https://uniapp.dcloud.net.cn/tutorial/nvue-outline.html"></u--text>
</view>
</template>
<script>
import {
i18n
} from '@/common/util/i18n.js'
export default {
data() {
return {
i18n
};
}
}
</script>
pages.json国际化
pages.json不属于vue页面,其中的原生tabbar和原生导航栏里也有文字内容。这部分国际化要特别注意,只能写在项目根目录的locale目录下配置语言json文件,我尝试过写在common/i18n
,发现并没有生效,细想也能理解,因为这些内容的国际化在项目加载之前就生成了
// 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隐私提示语的国际化
"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" : "獲取用戶監視器許可權,用於更改頭像資訊時拍照上傳照片,是否允許使用監視器"
}
}
}
}
详细用法见应用云端打包国际化处理
应用名国际时,慎用以下方式,我遇到在本地调试时,经常提示异常。异常现象
和 pages.json
一致,在项目根目录增加locale/uni-app.语言地区代码.json
文件,然后在 manifest.json
中使用%%
占位
{
"name" : "%app.name%",
}
遇到问题
- 如何将语言包按模块拆分,方便后期维护
官网是直接引用多语言的json文件,考虑到json文件不好进行模块拆分,把项目中所有的多语言都配置在同一个文件,会导致后期维护麻烦,本项目示例中按模块进行拆分。具体的可查看@/common/i18n/
(业务中使用的国际化语言包)。
- nvue页面国际化问题
考虑到项目可能会有多个nvue页面,把nvue页面需要引入的uni-i18n提成一个js,方便公用,后续调用与vue页面类似
- mainfest.json应用名称国际化后,自定义基座运行后提示异常
按照官网提示的示例,在项目根目录增加 locale/uni-app.语言地区代码.json 文件,然后在 manifest.json 中使用 %% 占位,自定义基座运行时,会提示如下异常,正式包打包应用名又能正常显示。
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 也可以在插件市场下载uniapp国际化应用与示例
特别感谢
本项目使用的UI框架,界面风格大气,上手简单 uView