全局过滤器必须在 main.js 中用 vue.filter() 注册,且须在 new vue() 前完成;函数签名强制为 (value, args),需校验 value 空值;推荐集中导出+循环注册,禁止异步、副作用及跨平台 api 调用。

全局过滤器必须在 main.js 中用 Vue.filter() 注册
只新建 filters/index.js 文件、写好函数,但没在 main.js 里调用 Vue.filter(),过滤器就完全不生效——模板里 {{ value | myFilter }} 会静默渲染为空,控制台也不报错。
根本原因是:Vue 2(uni-app 当前主流基础)的过滤器机制是纯手动挂载,不扫描文件、不识别目录约定、不自动 import。它只认 Vue.filter('name', fn) 这一种注册方式,且必须发生在 new Vue({}) 之前。
-
main.js是唯一合法注册入口,App.vue、页面onLoad或组件created里调用都太晚,实例已创建,注册无效 - 如果你用的是 vue-cli 或 vite 模式,确保路径是项目根目录下的
main.js,不是src/main.js(后者可能被构建忽略) - 注册顺序很重要:所有
Vue.filter()调用必须在const app = new Vue({})之前,否则部分页面可能漏注册
过滤器函数签名必须是 (value, args),不能省略 value
常见错误是写成箭头函数却漏掉第一个参数,比如 (format) => {...},导致模板中传入的原始值变成 undefined,后续逻辑全崩。
正确签名强制为两个参数:value(管道符左边的值)是必传且不可省略的;args(如格式字符串、配置对象)才是可选的后续参数。
- 错误示例:
Vue.filter('formatDate', (fmt) => { return new Date().toLocaleDateString('zh-CN', { ... }) })——fmt被当成了value,原始时间值丢了 - 正确写法:
Vue.filter('formatDate', (value, fmt = 'yyyy-MM-dd') => { if (!value) return ''; const d = new Date(value); /* ... */ }) - 务必对
value做空值判断:null、''、0、undefined都可能导致new Date(value)返回Invalid Date
推荐集中管理 + 批量注册,别手写每个 Vue.filter()
把所有过滤器收在一个文件(如 @/common/filters/index.js),导出为对象,再在 main.js 里循环注册,既清晰又防遗漏。
例如 index.js 内容:
export default {
formatDate(value, fmt) { /* ... */ },
phoneMask(value) { /* ... */ },
statusText(value) { /* ... */ }
}
main.js 中注册:
import filters from '@/common/filters'
Object.keys(filters).forEach(key => {
Vue.filter(key, filters[key])
})
- 避免在
main.js里直接写一堆Vue.filter('xxx', () => {}),维护成本高、易漏、难测试 - 不要在过滤器里调用
uni.getSystemInfoSync()、document或this—— 过滤器无组件上下文,跨平台时会报错 - 所有过滤器必须是纯函数:无副作用、无异步、不改全局状态,否则链式调用时行为不可预测
模板中使用时注意语法边界和平台限制
{{ value | filterName }} 是唯一合法写法,任何加括号、嵌套表达式、命名参数都会编译失败或静默失效。
- 错误:
{{ value | filterName('a', 'b') }}—— Vue 2 不支持多参数直接传入,会报Invalid expression - 正确方案一:把多参封装进一个对象,
{{ value | mergeOptions({ type: 'list', size: 20 }) }} - 正确方案二:拆成单参过滤器链,
{{ value | withType('list') | withSize(20) }} -
v-bind中使用必须不加引号::placeholder="msg | toUpper"(不是":placeholder='msg | toUpper'") - 避免在
v-for中对未初始化数据调用,如v-for="item in list"但list初始为undefined,会触发Cannot read property 'xxx' of undefined
真正容易被忽略的是:过滤器在 v-for 里高频执行时没有缓存,每次重渲染都重新计算。如果涉及正则、JSON.parse 或深层条件判断,性能会明显下降——这类逻辑该提前放在 computed 或请求响应后处理,别堆在模板里。










