uni-app 全局过滤器仅 Vue 2 模式下有效,Vue 3 及小程序端(微信/支付宝/字节)不支持;必须在 main.js 中 new Vue 前用 Vue.filter 注册,H5 可用,其余端静默失效,推荐改用纯函数+计算属性。

uni-app 里定义全局过滤器,只在 Vue 2 模式下有效;Vue 3(即使用 @vue/composition-api 或 setup 语法)中 Vue.filter 已被官方移除,且小程序端(微信/支付宝/字节)根本不会执行 filters —— 不是写错了,是平台不支持。
全局过滤器只能在 main.js 中用 Vue.filter 注册
这是唯一生效的位置,且仅限 Vue 2 兼容模式(即项目未启用 Vue 3 构建)。H5 端能跑通,其他端基本无效。
-
Vue.filter必须在new Vue({ App })实例创建前调用,否则过滤器注册失败 - 函数参数名必须是
value(或任意名),但不能漏掉它;比如(date) => { ... }是合法的,() => { ... }会拿不到原始值 - 注意别把
getDay()当成「日期」——它是星期几(0–6),真正取日要用getDate() - 示例正确写法:
Vue.filter('formatDate', (value) => { const d = new Date(value) const y = d.getFullYear() const m = String(d.getMonth() + 1).padStart(2, '0') const day = String(d.getDate()).padStart(2, '0') return `${y}-${m}-${day}` })
filters 在小程序里不执行的典型现象
模板写了 {{ timestamp | formatDate }},但页面显示原样时间戳或空值,控制台无报错 —— 这不是逻辑错误,是编译时被跳过。
- 微信小程序基础库 2.20.0+、支付宝 10.2.90+ 均未实现
filters编译支持 - App 端(iOS/Android)使用的是原生 WebView 渲染,
filters不参与 diff 过程,直接忽略 - 真机调试时,哪怕 H5 端看到效果,也不能推断其他端可用
- 如果你发现某个 filter “偶尔生效”,大概率是缓存了旧 H5 包,或误用了局部
filters对象(页面级定义)
替代方案:用函数 + 计算属性 / setup 函数更可靠
跨端一致性要求高的项目,应放弃 filters,改用可显式调用的格式化函数。
- 把格式化逻辑抽到
/common/filters.js,导出纯函数:export const formatDate = (value, format = 'YYYY-MM-DD') => { const d = new Date(value) // 实现逻辑(推荐用 dayjs 或 date-fns,避免手撕) return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}` } - 在页面中 import 后,用计算属性或
setup内调用:const formattedDate = computed(() => formatDate(props.date))
或const formattedDate = formatDate(dateRef.value)
- 金额类场景必须用
Intl.NumberFormat,不要手写千分位正则 —— 小程序低基础库对maximumFractionDigits支持不稳,固定用minimumFractionDigits: 2更安全
真正容易被忽略的点是:你以为在 main.js 注册了就“全局可用”,但 uni-app 的多端编译机制决定了,只有 H5 端会把它当真。其他端要么静默失效,要么报 filter not found 却不抛错 —— 所以只要涉及微信/支付宝小程序,就别碰 Vue.filter。


















