H5能用过滤器而小程序不能是因底层机制差异:H5走Vue 2模板编译,|被解析为过滤器调用;小程序用JSON数据驱动,|被当作文本原样输出。需满足Vue 2模式、Vue.filter在new Vue()前注册、模板严格写成{{ value | filterName }}。

能用,但只限 H5,且必须满足三个硬性条件:Vue 2 模式、Vue.filter 在 new Vue() 之前注册、模板中写法严格符合 {{ value | filterName }}。
为什么 H5 能用而小程序不能用
不是 bug,是底层机制差异。H5 端走的是标准 Vue 2 的 template 编译流程,| 会被解析为过滤器调用;小程序端(微信/支付宝/字节)使用 JSON 数据驱动 + 自定义组件树,模板里的 | 根本不进 JS 执行上下文——它被当作文本原样输出,既不报错也不执行。
- 检查项目是否为 Vue 2 模式:看
package.json中@dcloudio/uni-app版本是否低于3.0.0 - 确认运行时:H5 真机或浏览器调试器里执行
Vue.version,应返回"2.6.14"类似值 - 别在 App.vue 或页面里注册:
Vue.filter必须出现在main.js中、且在new Vue({ ... })调用之前
怎么正确注册和使用一个格式化时间的 filter
常见错误是漏掉 value 参数、没做空值防护、或把过滤器写在组件内。下面是一个安全可用的 formatDate 示例:
// main.js
import Vue from 'vue'
// ✅ 必须放在 new Vue 之前
Vue.filter('formatDate', (value, format = 'yyyy-MM-dd') => {
if (!value) return ''
const d = new Date(value)
if (isNaN(d.getTime())) return ''
const year = d.getFullYear()
const month = String(d.getMonth() + 1).padStart(2, '0')
const day = String(d.getDate()).padStart(2, '0')
if (format === 'yyyy-MM-dd') return `${year}-${month}-${day}`
return d.toLocaleDateString('zh-CN')
})
new Vue({
// ...
})
- 第一个参数
value不可省略,它是管道符左边传入的原始值 - 必须判断
!value和isNaN(d.getTime()),否则后端返回null或空字符串会导致白屏 - 模板中只能写
{{ timestamp | formatDate }}或{{ timestamp | formatDate('MM/dd/yyyy') }},不能写成{{ timestamp | formatDate('MM/dd/yyyy') | uppercase }}(链式多 filter 在 uni-app 2.x 中不支持)
为什么 {{ msg | toUpper }} 在 v-bind 里会报错
因为 v-bind 的值是表达式,不是字符串。写成 :placeholder="msg | toUpper" 是对的;写成 :placeholder="msg | toUpper"(带引号)就错了——引号会让 Vue 把它当纯字符串,不再解析管道符。
立即学习“前端免费学习笔记(深入)”;
- 所有
v-bind绑定都不要加引号,除非你真想传字符串字面量 - 过滤器不能在
v-if、v-for的判断条件里使用,比如v-if="status | statusText === '已通过'"是非法语法 - 过滤器函数内禁止调用
this、uni、document等平台 API,它没有组件实例上下文
真正容易被忽略的是:H5 页面里 filter 看似生效,但一旦你升级到 uni-app 3.x(哪怕只是试用),Vue.filter 会直接报错,模板中的 | 全部失效——这不是配置问题,是 Vue 官方已移除该 API。跨端项目现在就该开始用 computed 或工具函数替代,别等升级那天再改。


















