uni.setLocale不能实时切换App端语言,因它仅设置locale标识且冷启动生效;热切换需重载页面并重置i18n实例,确保locale更新并响应。

App端国际化切换不能靠 uni.setLocale 实时生效——它只在冷启动时读取,热切换必须手动重载页面或重建 Vue 实例。
uni-app 的 uni.setLocale 为什么切不了语言?
这个 API 名字有误导性:它实际只是设置全局 locale 标识,并不会触发 i18n 翻译更新。App 端(iOS/Android)的 native 层语言由系统决定,uni.setLocale 只影响部分内置组件(比如 picker 的标题),不联动 $t 或 uni.$t。
- 调用
uni.setLocale('zh-Hans')后,$t('hello')仍返回旧语言文本 - H5 和小程序端表现不同:H5 支持部分响应式更新,App 端完全不响应
- 真正起作用的是你初始化 i18n 实例时传入的
locale值,后续改它没用
App 端多语言切换的正确做法:手动 reload + i18n 实例重置
核心思路是:语言变更后,清空当前页面状态,强制重新渲染;同时确保 i18n 实例的 locale 被更新并通知所有组件响应。
- 用
uni.getLocale()读取当前设置(仅作参考,不可靠) - 把语言 code 存进
uni.setStorageSync('lang', 'en-US'),避免重启丢失 - 切换时调用
uni.reLaunch({ url: '/pages/index/index' })或uni.redirectTo,让页面重建 - 在
main.js或app.js中,每次启动都根据 storage 重新 new 一个 i18n 实例,而不是复用旧实例 - 不要在
Vue.prototype上挂载 i18n 实例——App 端页面重建后原型链会断
vue-i18n v9(uni-app 3.0+ 推荐)怎么配才不翻车?
uni-app 3.x 默认支持 vue-i18n v9,但它的 Composition API 写法和 legacy 模式行为差异大,App 端尤其敏感。
- 必须用
createI18n({ legacy: false, locale: savedLang }),否则useI18n()在子组件里拿不到最新 locale -
locale.value = 'ja'是有效的,但仅限 setup() 内;模板中仍要靠{{ $t('key') }},它会自动响应 - 避免在
onLoad里调用useI18n()—— 页面生命周期早于 i18n 初始化,会拿空对象 - 翻译资源建议按模块拆成对象,用
i18n.mergeLocaleMessage('zh-Hans', { home: {...} })动态加载,减少首屏体积
App 端语言切换后日期/数字格式还是英文?
因为 Intl API 在 App 端(尤其是 Android)默认不随 uni.setLocale 变,得手动传参。
-
new Date().toLocaleDateString('zh-CN')必须显式传语言码,不能依赖系统 - 用
useI18n().locale.value动态拼接:date.toLocaleDateString(useI18n().locale.value) - uni-app 自带的
uni.getSystemInfoSync().language返回的是系统语言,不是你设的,别直接拿来格式化 - 第三方库如
dayjs需手动dayjs.locale('zh-cn'),且要确保对应 locale 文件已 import
App 端 i18n 最难缠的不是翻译本身,而是「你以为改了 locale 就生效」这个错觉——所有响应式更新、格式化、甚至路由守卫里的语言判断,都得绕开系统 API,走自己维护的 language state。










