全局mixin中不能注册过滤器,Vue.filter()必须在main.js中new Vue()前调用;过滤器需抽成纯函数并在main.js批量注册,Vue 3已移除过滤器支持。

全局 mixin 里不能注册过滤器,Vue.filter() 必须在 main.js 中调用
过滤器(filter)和混入(mixin)是两个完全独立的机制,不能混用。你在 app.mixin() 或 Vue.mixin() 里写 Vue.filter() 不会生效——因为此时 Vue 构造函数已初始化完毕,Vue.filter() 只在实例创建前有效。
常见错误是把过滤器逻辑塞进 mixin 的 methods 或 computed,然后试图在模板里用 {{ value | myFilter }} 调用,结果静默失败:不报错、不渲染、值消失。
-
Vue.filter()是 Vue 2 全局 API,只认main.js(或main.ts)中new Vue()/createApp()之前的调用 - mixins 作用于组件实例,而 filter 是模板编译期绑定的语法糖,两者生命周期和注册时机完全不同
- 即使你用
app.config.globalProperties.$myFilter = ...挂载函数,模板里|语法也识别不了——它只找Vue.options.filters里的注册项
想复用过滤器逻辑?抽成纯函数 + 在 main.js 批量注册
真正可落地的做法是:把过滤器逻辑写成独立的纯函数,统一存放在 common/filters/index.js,再在 main.js 中 import 并逐个注册。
例如:
// common/filters/index.js
export const 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')
}
export const toUpper = (value) => {
return typeof value === 'string' ? value.toUpperCase() : value
}
然后在 main.js 开头注册:
// main.js
import { formatDate, toUpper } from '@/common/filters'
Vue.filter('formatDate', formatDate)
Vue.filter('toUpper', toUpper)
// ⚠️ 必须放在 new Vue({}) 之前
new Vue({ ... })
- 函数必须严格遵循
(value, ...args)签名,第一个参数不可省略 - 避免在函数内调用
uni.xxx或document,保证跨平台安全 - 所有参数都得是同步、无副作用的;异步、API 调用、
this访问一概禁止
为什么有人想在 mixin 里“注入”过滤器?其实是混淆了使用场景
多数人实际要的是“让多个页面共享格式化逻辑”,但误以为 mixin 是“通用代码容器”。其实:
- 如果只是想在 JS 里调用(比如
methods中处理数据),直接 import 函数更轻量、更可控 - 如果要在模板里用
|语法,就必须走Vue.filter()注册路径,别绕弯 - 如果需要动态参数(如当前语言、用户偏好),过滤器本身不支持响应式依赖,得改用
computed或封装为方法调用
比如日期格式需随 locale 变化,就不能靠 {{ date | formatDate }},而应写成 {{ $formatDate(date, $locale) }},并在 main.js 挂到 Vue.prototype.$formatDate 上。
Vue 3(uni-app 3.x)已彻底移除过滤器,别再设计新依赖
如果你的 package.json 里 @dcloudio/uni-app 版本 ≥ 3.0.0-alpha,Vue.filter() 会直接报错,{{ value | xxx }} 语法也不再解析。
此时唯一兼容方案是:
- 模板中改用方法调用:
{{ formatDate(date) }}(需确保formatDate在当前组件作用域可用) - 或统一挂到
app.config.globalProperties.$filters = { formatDate, toUpper },再在组件中setup()里解构使用 - 全局混入此时反而更合适做这类挂载,但注意:它解决的是“JS 调用”,不是“模板管道符”
真正容易被忽略的是:很多团队升级到 uni-app 3 后,仍保留着大量 | 写法,上线后模板字段全空,控制台却没报错——因为 Vue 3 直接忽略未知管道符,连 warning 都不抛。


















