uni-app 3.x 已彻底移除 filters,应改用 computed(配合可选链与空值合并)、watch(处理副作用)及请求拦截器统一标准化响应数据,并用 getErrorMessage 等工具函数兜底错误提示。

uni-app 3.x 里 filter 已失效,别再写 {{ data | format }}
uni-app 3.x 基于 Vue 3,彻底移除了 filters 配置项和模板过滤器语法。你在 .vue 文件中写 {{ error?.msg | friendlyMsg }},H5 端可能侥幸渲染,但微信/支付宝小程序编译时直接忽略,App 端报 filter is not defined 错误。这不是兼容性问题,是能力已被删除。
根本原因在于:Vue 3 的响应式系统和模板编译机制不再支持运行时函数注入到插值表达式中;uni-app 小程序平台更无法在 WXML 层还原这种逻辑。
- 不要试图用
app.config.globalProperties.$filters = {...}注册——uni-app 不走 Vue 的 runtime-core 流程,无效 - 不要在
main.js或App.vue里 mock 一个filters对象——模板编译阶段已跳过解析 - 已废弃的写法包括:
filters: { defaultNull() {...} }、Vue.filter('upper', ...)
异步数据还没回来时,computed 可能返回 undefined 导致渲染崩溃
很多人把错误提示或字段兜底逻辑塞进 computed,比如:computed(() => res.data?.message || '加载失败')。但若 res 是 ref(null) 或初始为 undefined,这个表达式会直接报 Cannot read property 'data' of null,页面白屏或字段消失。
关键不是“能不能用 computed”,而是“怎么写才安全”。防御必须前置到取值链最开始:
- 用可选链 + 空值合并:
computed(() => response.value?.data?.message ?? response.value?.msg ?? '请求失败') - 避免在 computed 内调用副作用(如
uni.showToast),它只该返回值,不该触发 UI 行为 - 如果需要 toast 提示,改用
watch监听response变化,且加判空:watch(response, (newVal) => { if (newVal?.statusCode >= 400) uni.showToast({ title: getErrorMessage(newVal) }) })
真正统一处理异步返回数据,得从 request 层拦截
模板层没法“统一”——每个 {{ }} 都是孤立表达式;computed 只管单个字段。要让所有接口的 null、undefined、字段名不一致等问题自动归一,唯一可靠位置是请求响应拦截器。
在封装的 request 函数 success 回调里做标准化处理,例如:
success: (res) => {
if (res.statusCode === 200) {
// 统一清洗 data 中的 null/undefined
const cleaned = deepReplaceNull(res.data, '')
// 统一错误字段提取
const error = res.data?.error || res.data?.message || res.data?.msg
resolve({ ...cleaned, _error: error })
}
}
这样下游组件拿到的永远是结构可控的对象,不用每个地方都写三元判断。注意:deepReplaceNull 别用 JSON.parse(JSON.stringify(obj))——它会吃掉 Date、undefined、循环引用。
后端字段名不统一?写个 getErrorMessage 工具函数比硬编码强
你不能指望所有接口都返回 { message: 'xxx' }。真实项目里,有的错在 res.data.errMsg,有的在 res.msg,还有的嵌套三层:res.data.result.error.desc。硬写 res.data.message 必崩。
推荐收口一个纯函数,在 utils/request.js 里导出:
export function getErrorMessage(res) {
return (
res?.data?.errMsg ||
res?.data?.error?.message ||
res?.data?.message ||
res?.data?.msg ||
res?.errMsg ||
res?.message ||
res?.msg ||
'网络异常,请稍后重试'
)
}
这个函数被 watch、computed、甚至 onShow 里手动调用都行,关键是它不依赖响应式上下文,类型安全,且所有分支都做了可选链防护。别漏掉对 res 本身为 string 或 null 的兜底——有些网关错误直接返回纯文本 HTML。
最常被忽略的一点:这个函数必须在 fail 回调里也用一次。因为 uni.request 的 fail 参数(如超时、DNS 失败)是原生错误对象,没有 data 字段,直接访问 res.data 会报错。


















