uni-app中$t过滤器不能直接用于模板,因app端vue运行时不支持自定义过滤器,且vue-i18n@9无$t过滤器、@8默认不注册;应改用computed或methods封装$t调用,并配合页面重载确保语言切换生效。

uni-app里$t过滤器为什么不能直接用在模板里
因为uni-app的Vue运行时(尤其App端)不支持自定义过滤器语法,vue-i18n@9(Vue 3)根本没提供$t过滤器,vue-i18n@8(Vue 2)虽有但默认不注册为全局过滤器——你写{{ msg | $t }}会报filter not found。
替代方案:用计算属性包裹$t调用
把翻译逻辑收进computed,既保持响应式,又避开过滤器限制。关键点是让 Vue 能监听语言变更:
- 别直接在模板里写
{{ $t('home.title') }},它不会随i18n.locale变化自动重算 - 改用
computed返回一个对象,例如:computed: { lang() { return { title: this.$t('home.title'), desc: this.$t('home.desc') } } } - 模板中引用
{{ lang.title }},这样语言切换后会触发重计算
如果坚持要“过滤器感”,用方法代替
在methods里封装$t调用,虽然不是真正过滤器,但写法接近且可靠:
- 定义
methods: { t(key) { return this.$t(key) } } - 模板中写
{{ t('home.title') }}——注意这不是响应式,需配合watch或页面重载 - 仅推荐用于H5/小程序端;App端仍需
uni.reLaunch重建页面,否则t()返回旧值
动态key场景下必须手动触发更新
当翻译key本身是变量(如item.type + '.label'),$t调用不会自动追踪key变化。这时必须让组件“感知”语言和key双重变化:
- 把key和locale都纳入
computed依赖:computed: { dynamicLabel() { const key = this.item.type + '.label' return this.$t(key) } } - 或者用
watch监听item.type,手动调用this.$forceUpdate()(不推荐)或触发uni.reLaunch - 更稳妥的做法:语言切换后统一重载页面,避免状态错位
真正容易被忽略的是:App端无论用哪种写法,只要没重建i18n实例+重载页面,$t就永远返回旧语言内容——这不是语法问题,是平台限制。











