直接用 uni.getSystemInfoSync().language 作 i18n locale 会翻车,因 Android 返回 zh/en、iOS 返回 zh-Hans/en-US,而语言包多为 zh-CN/en-US;需统一映射并 fallback 默认语言,且 i18n 实例须每次页面重建时按 storage 中真实 locale 重新初始化。

uni.getSystemInfoSync().language 返回值怎么用才不翻车
直接拿 uni.getSystemInfoSync().language 当作 i18n 的 locale 用,90% 情况下会匹配失败。Android 返回 zh、en 这类简写;iOS 返回 zh-Hans、en-US 这种带区域码的完整标识;而你的语言包名(比如 zh-CN.json)和 i18n 初始化时写的 locale: 'zh-CN' 往往是第三种格式。
实操建议:
- 统一做映射:把
zh→zh-CN,zh-Hans→zh-CN,en→en-US,en-US→en-US - 不要硬编码判断
res.language.includes('zh'),它会漏掉zh-Hant(繁体)、zh-HK等 - 兜底逻辑必须有:匹配不到就 fallback 到默认语言(如
zh-CN),避免整个 app 文字变空
App 启动时怎么让 vue-i18n 读到系统语言
不能在 main.js 里直接用 uni.getSystemInfoSync() —— App 端该 API 在某些 Android 机型上冷启动时可能未就绪,返回 undefined 或空字符串。
实操建议:
- 把语言探测逻辑挪到
App.vue的onLaunch生命周期里,这里保证环境已初始化 - 用
uni.getSystemInfo(异步版)+Promise.race加超时兜底,避免卡死 - 拿到系统语言后,立刻存进
uni.setStorageSync('app_locale', locale),防止后续页面读不到 - i18n 实例必须在每次页面重建时重新 new,不能复用旧实例——App 端页面 reload 后 Vue 原型链重置,挂载在
Vue.prototype上的$i18n会失效
切换语言后 TabBar 和导航栏文字怎么同步更新
TabBar 是原生组件,不响应 Vue 数据变化;导航栏标题(uni.setNavigationBarTitle)也得手动调用。指望 $t('tab.home') 自动刷新纯属白等。
实操建议:
- 语言切换完成、页面重载前,先批量调用
uni.setTabBarItem更新每个 tab 的text和pagePath对应的图标(如有) - 在目标页面的
onLoad里调用uni.setNavigationBarTitle({ title: $t('nav.home') }),别只靠pages.json静态配置 - iOS 上若文字被截断,不是翻译问题,是中英文混排导致宽度计算异常,加
white-space: nowrap或固定width样式更稳
为什么日期/数字格式还是英文,明明语言切了
uni.setLocale 对 Intl API 完全无效。App 端(尤其 Android)的 Date.toLocaleDateString()、Number.toLocaleString() 默认走系统 locale,但不会随你 JS 里改的 i18n.locale.value 变。
实操建议:
- 所有格式化调用必须显式传参:
new Date().toLocaleDateString(useI18n().locale.value),不能省略 - 封装工具函数,比如
formatDate(date, locale = useI18n().locale.value),避免到处重复写 - 注意
useI18n().locale.value在setup()外不可用,非 Composition API 页面要用getCurrentInstance().proxy.$i18n.locale


















