HarmonyOS APP

uView Pro 所有内置组件均支持多语言,支持全局与组件级配置、响应式切换与持久化语言偏好。
核心特性
zh-CN 与 en-US。特别注意
组件库发布到 npm 的是未编译的 Vue 和 TypeScript 代码。由于 Vite 会预构建依赖到 node_modules/.vite,而国际化基于 reactive 实现数据共享,开发阶段可能导致页面使用预构建产物中的数据,而组件库使用内部数据,造成数据不同步。
非 uni_modules 模式下,需在 vite.config.ts 中添加配置排除预构建:
import { defineConfig } from 'vite'
export default defineConfig({
...
optimizeDeps: {
exclude: process.env.UNI_PLATFORM === 'h5' && process.env.NODE_ENV === 'development' ? ['uview-pro'] : []
}
...
})uni_modules 模式无需额外处理。
方式一:全局注册(main.ts):
app.use(uViewPro, { locale: 'zh-CN' })
// 或
import { zhCN, enUS } from 'uview-pro/locale';
app.use(uViewPro, {
locale: { locales: [zhCN, enUS], defaultLocale: 'zh-CN' }
})方式二:使用 u-config-provider 或 useLocale() 在组件级提供 locales 和 currentLocale。
<template>
<u-config-provider
:locales="locales"
:current-locale="currentLocale"
>
<!-- 你的应用内容 -->
<u-modal v-model="show" :content="content"></u-modal>
<u-button @click="open"> 打开模态框 </u-button>
</u-config-provider>
</template>
<script setup lang="ts">
import { useLocale } from 'uview-pro'
const { currentLocale, locales } = useLocale()
const show = ref<boolean>(false)
const content = ref<string>('东临碣石,以观沧海')
const open = () => {
show.value = true
}
</script>import { useLocale } from 'uview-pro';
const { setLocale } = useLocale()
setLocale('en-US')locale.locales 中传入部分字段,uView Pro 将与内置文案合并(深度覆盖)。// main.ts
app.use(uViewPro, {
theme: themes,
locale: {
locales: [{
name: 'zh-CN',
modal: {
confirmText: '好的', // 自定义确认按钮文案
cancelText: '算了' // 自定义取消按钮文案
},
upload: {
uploadText: '选择文件' // 自定义上传文案
}
}],
defaultLocale: 'zh-CN'
}
})src/locales/fr-FR.ts,包含 name 字段及组件文案),并在入口注册。所有字段见下方“语言包字段说明”章节。假设我们要为应用添加法语支持:
// 首先创建法语语言包文件
// src/locales/fr-FR.ts
export default {
name: 'fr-FR', // 必须要有
uActionSheet: {
cancelText: 'Annuler'
},
uModal: {
title: 'Avertissement',
content: 'Contenu',
confirmText: 'Confirmer',
cancelText: 'Annuler'
},
uCalendar: {
startText: 'Début',
endText: 'Fin',
confirmText: 'Confirmer',
toolTip: 'Sélectionner une date',
// ... 其他法语翻译
},
uUpload: {
uploadText: 'Sélectionner une image',
retry: 'Réessayer',
overSize: 'Le fichier dépasse la taille autorisée',
// ... 更多法语文案
},
// ... 继续添加其他组件的法语翻译
}注意
name 字段作为语言包的唯一标识。在入口注册时引入并添加该语言包:
// main.ts
import { createApp } from 'vue'
import uViewPro from 'uview-pro'
import frFR from './locales/fr-FR'
const app = createApp(App)
app.use(uViewPro, {
theme: themes,
locale: {
locales: [frFR], // 添加法语语言包
defaultLocale: 'fr-FR' // 设置默认语言为法语,为语言包中的name字段
}
})import { useLocale } from 'uview-pro';
const { t } = useLocale('uModal')
const text = t('confirmText') // 等价于 t('uModal.confirmText')
// 等价于
const { t } = useLocale();
const text = t('uModal.confirmText');t('welcome', { name: '张三' }) → "欢迎您,张三!"方案:使用 vue-i18n 管理业务文案,uView Pro 管理组件文案。
启动顺序建议先 app.use(i18n),再 app.use(uViewPro, { locale: { defaultLocale: ... } }),切换时同步两端语言即可。
首先你应该在项目中配置vue-i18n:
// src/locales/index.ts
import { createI18n } from 'vue-i18n';
import zhCN from './langs/zh-CN.json'; // 简体中文
import enUS from './langs/en-US.json'; // 英文
const messages = {
'zh-Hans': zhCN,
en: enUS,
};
// 自动检测用户语言
const getDefaultLocale = () => {
try {
const lang = uni.getLocale?.() || 'zh-Hans';
return lang.startsWith('zh') ? 'zh-Hans' : 'en';
} catch {
return 'zh-Hans';
}
};
const i18n = createI18n({
locale: getDefaultLocale(),
fallbackLocale: 'zh-Hans',
messages,
allowComposition: true,
legacy: false,
globalInjection: true
});
export default i18n;然后在main.ts中集成vue-i18n和uView Pro:
// main.ts
import { createSSRApp } from 'vue';
import App from './App.vue';
import i18n from './locales';
import uViewPro from 'uview-pro';
const app = createSSRApp(App);
// 先使用vue-i18n
app.use(i18n);
// 再使用uView Pro,并配置国际化
app.use(uViewPro, {
locale: {
// 设置 'zh-CN' 为默认语言
defaultLocale: 'zh-CN'
}
});将 vue-i18n 的 locale 与 uView Pro 的 setLocale() 进行映射(如 zh-Hans ↔ zh-CN)。
import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { useLocale } from 'uview-pro';
const { t, locale } = useI18n();
const { setLocale } = useLocale();
type LocaleKey = 'zh-Hans' | 'en';
const handleLocaleChange = (value: LocaleKey) => {
// 设置vue-i18n语言
locale.value = value;
// 设置系统语言
uni.setLocale(value);
// 设置uView Pro语言
const uViewLocale = value === 'zh-Hans' ? 'zh-CN' : 'en-US';
setLocale(uViewLocale);
};
// 切换到英文
handleLocaleChange('en');
// 切换到中文
handleLocaleChange('zh-Hans');useLocale() → 返回 { t, setLocale, currentLocale, locales }。t(key, params?) → 获取翻译字符串并支持参数替换。setLocale(name) → 切换语言(例如 zh-CN / en-US)。uView Pro 的 i18n 旨在提供实用、可扩展且易集成的组件文案国际化能力。项目中建议用 vue-i18n 管理业务文案,uView Pro 管理组件文案,切换时同步即可。
uview Pro 默认支持 2 个语言包(中文、英文),更多语言包请自行添加,下述为所有字段:
export default {
name: 'zh-CN', // 必要
label: '简体中文', // 必要
locale: 'zh-Hans', // 必要
uActionSheet: {
cancelText: '取消'
},
uUpload: {
uploadText: '选择图片',
retry: '点击重试',
overSize: '超出允许的文件大小',
overMaxCount: '超出最大允许的文件个数',
reUpload: '重新上传',
uploadFailed: '上传失败,请重试',
modalTitle: '提示',
deleteConfirm: '您确定要删除此项吗?',
terminatedRemove: '已终止移除',
removeSuccess: '移除成功',
previewFailed: '预览图片失败',
notAllowedExt: '不允许选择{ext}格式的文件',
noAction: '请配置上传地址'
},
uVerificationCode: {
startText: '获取验证码',
changeText: 'X秒重新获取',
endText: '重新获取'
},
uSection: {
subTitle: '更多'
},
uSelect: {
cancelText: '取消',
confirmText: '确认'
},
uSearch: {
placeholder: '请输入关键字',
actionText: '搜索'
},
uNoNetwork: {
tips: '哎呀,网络信号丢失',
checkNetwork: '请检查网络,或前往',
setting: '设置',
retry: '重试',
noConnection: '无网络连接',
connected: '网络已连接'
},
uReadMore: {
closeText: '展开阅读全文',
openText: '收起'
},
uPagination: {
prevText: '上一页',
nextText: '下一页'
},
uPicker: {
cancelText: '取消',
confirmText: '确认'
},
uModal: {
title: '提示',
content: '内容',
confirmText: '确认',
cancelText: '取消'
},
uLoadmore: {
loadmore: '加载更多',
loading: '正在加载...',
nomore: '没有更多了'
},
uLink: {
mpTips: '链接已复制,请在浏览器打开'
},
uKeyboard: {
cancelText: '取消',
confirmText: '确认',
number: '数字键盘',
idCard: '身份证键盘',
plate: '车牌号键盘'
},
uInput: {
placeholder: '请输入内容'
},
uCalendar: {
startText: '开始',
endText: '结束',
toolTip: '选择日期',
outOfRange: '日期超出范围啦~',
year: '年',
month: '月',
sun: '日',
mon: '一',
tue: '二',
wed: '三',
thu: '四',
fri: '五',
sat: '六',
confirmText: '确定',
to: '至'
},
uEmpty: {
car: '购物车为空',
page: '页面不存在',
search: '没有搜索结果',
address: '没有收货地址',
wifi: '没有WiFi',
order: '订单为空',
coupon: '没有优惠券',
favor: '暂无收藏',
permission: '无权限',
history: '无历史记录',
news: '无新闻列表',
message: '消息列表为空',
list: '列表为空',
data: '数据为空'
},
uCountDown: {
day: '天',
hour: '时',
minute: '分',
second: '秒'
},
uFullScreen: {
title: '发现新版本',
upgrade: '升级'
}
};export default {
name: 'en-US', // 必要
label: 'English', // 必要
locale: 'en', // 必要
uActionSheet: {
cancelText: 'Cancel'
},
uUpload: {
uploadText: 'Select Image',
retry: 'Retry',
overSize: 'File size exceeds allowed limit',
overMaxCount: 'Exceeds maximum allowed number of files',
reUpload: 'Re-upload',
uploadFailed: 'Upload failed, please try again',
modalTitle: 'Notice',
deleteConfirm: 'Are you sure you want to delete this item?',
terminatedRemove: 'Removal cancelled',
removeSuccess: 'Removed successfully',
previewFailed: 'Failed to preview image',
notAllowedExt: 'Files with {ext} format are not allowed',
noAction: 'Please configure upload address'
},
uVerificationCode: {
startText: 'Get Code',
changeText: 'Retry in Xs',
endText: 'Retry'
},
uSection: {
subTitle: 'More'
},
uSelect: {
cancelText: 'Cancel',
confirmText: 'Confirm'
},
uSearch: {
placeholder: 'Please enter keywords',
actionText: 'Search'
},
uNoNetwork: {
tips: 'Ooops, network disconnected',
checkNetwork: 'Please check network or go to',
setting: 'Settings',
retry: 'Retry',
noConnection: 'No network connection',
connected: 'Network connected'
},
uReadMore: {
closeText: 'Read More',
openText: 'Collapse'
},
uPagination: {
prevText: 'Prev',
nextText: 'Next'
},
uPicker: {
cancelText: 'Cancel',
confirmText: 'Confirm'
},
uModal: {
title: 'Notice',
content: 'Content',
confirmText: 'Confirm',
cancelText: 'Cancel'
},
uLoadmore: {
loadmore: 'Load more',
loading: 'Loading...',
nomore: 'No more'
},
uLink: {
mpTips: 'Link copied, please open it in browser'
},
uKeyboard: {
cancelText: 'Cancel',
confirmText: 'Confirm',
number: 'Number Keyboard',
idCard: 'ID Card Keyboard',
plate: 'Plate Keyboard'
},
uInput: {
placeholder: 'Please enter'
},
uCalendar: {
startText: 'Start',
endText: 'End',
toolTip: 'Select date',
outOfRange: 'Date out of range',
year: '',
month: '',
sun: 'Sun',
mon: 'Mon',
tue: 'Tue',
wed: 'Wed',
thu: 'Thu',
fri: 'Fri',
sat: 'Sat',
confirmText: 'Confirm',
to: ' to '
},
uEmpty: {
car: 'Shopping cart is empty',
page: 'Page not found',
search: 'No search results',
address: 'No shipping address',
wifi: 'No WiFi',
order: 'No orders',
coupon: 'No coupons',
favor: 'No favorites',
permission: 'No permission',
history: 'No history',
news: 'No news',
message: 'No messages',
list: 'No list',
data: 'No data'
},
uCountDown: {
day: 'days',
hour: 'hours',
minute: 'minutes',
second: 'Second'
},
uFullScreen: {
title: 'New Version Available',
upgrade: 'Upgrade'
}
};