uni-app 中 filters 无法用于国际化,因其不响应 locale 变更、不支持异步加载且 nvue 不兼容;应改用 computed + usei18n() 实现响应式翻译。

uni-app 里没有 Vue 2 那种全局 Vue.filter 的过滤器机制,更不能靠它做国际化转换——它不响应 i18n.locale 变更,也不支持异步加载语言包,硬写会卡死或漏翻译。
为什么 filters 在 uni-app 多语言场景下必然失效
Vue 3 已移除 filters API,uni-app 3.x(主流版本)默认基于 Vue 3;即使你用 Vue 2 模式,filters 是纯同步函数,无法访问 useI18n() 返回的响应式 locale 或异步加载的 message 包。常见现象包括:
- 切换语言后,
{{ 'home' | i18nFilter }}仍显示旧文案 - 首次启动时语言未就绪,
filters拿到空字符串或undefined - nvue 页面完全不支持
filters,直接报错filter is not defined
替代方案:用 computed + useI18n() 实现响应式翻译
这是 App/H5/小程序三端都稳定生效的方式,且能自动响应语言变更。关键点是:必须在 setup() 内调用 useI18n(),并用 computed 包裹 t() 调用。
- 不要在
data()或methods里直接调this.$t('key')—— App 端页面重载后this.$i18n可能为undefined - 模板中写
{{ t('button.submit') }},其中t是computed(() => i18n.t('button.submit')) - 若需复用,可封装成组合函数
useI18nKey('button.submit'),内部用computed返回响应式翻译值
如果必须用过滤器风格(比如迁移旧项目),用 globalProperties 挂载函数
这不是推荐做法,但可临时兼容。重点在于:该函数必须内部读取当前 i18n.locale.value 并调用 t(),不能缓存结果。
- 在
main.js初始化 i18n 后,加:app.config.globalProperties.$tKey = (key) => i18n.t(key) - 模板中仍写
{{ $tKey('nav.home') }},而非{{ 'nav.home' | tFilter }} - 禁止在
filters对象里定义函数——uni-app 不解析它,写了也白写 - 该方式在 nvue 页面无效,必须改用
computed方案
容易被忽略的坑:日期/数字类“翻译”根本不是 i18n 负责
$t() 只管静态文案,new Date().toLocaleDateString() 这类原生 API 的格式化结果,由系统 Intl 和显式传参决定,和 i18n.locale 无关。App 端尤其明显:
- 哪怕
i18n.locale.value === 'zh-CN',new Date().toLocaleDateString()仍可能输出英文格式 - 正确写法是显式传参:
new Date().toLocaleDateString(i18n.locale.value) - 数字同理:
(1234.56).toLocaleString(i18n.locale.value) - 别指望过滤器自动帮你补这个参数——它没能力读取 locale 响应式变量











