uni-app 不能直接用 Vue 2 的 filters,因 Vue 3 已官方移除该 API,uni-app 3.x 随之废弃;编译时会报“filters is not supported in Vue 3”错误,非平台兼容问题而是根本性弃用。

uni-app 里为什么不能直接用 Vue 2 的 filters
uni-app(尤其是基于 Vue 3 的项目)已完全移除 filters 选项,编译时会报错 filters is not supported in Vue 3。这不是 uni-app 的限制,而是 Vue 3 官方弃用所致。你看到的“过滤器失效”“模板中调用报错”,基本都源于此。
用 app.config.globalProperties 挂载方法到全局(Vue 3 兼容写法)
在 main.js(或 main.ts)中,通过 app.config.globalProperties 挂载函数,即可在任意 .vue 文件的模板和逻辑中使用,效果接近旧版 filters,但更灵活、类型友好。
示例:挂载一个格式化手机号的方法
// main.js
import { createSSRApp } from 'vue'
import App from './App.vue'
export function createApp() {
const app = createSSRApp(App)
// 挂载到全局,模板中可用 this.$formatPhone,js 中可用 getCurrentInstance().proxy.$formatPhone
app.config.globalProperties.$formatPhone = (phone) => {
if (!phone || String(phone).length !== 11) return ''
return String(phone).replace(/(\d{3})(\d{4})(\d{4})/, '$1-$2-$3')
}
return {
app
}
}
模板中调用:
<template>
<view>{{ $formatPhone('13812345678') }}</view>
</template>
在 setup 语法糖(<script setup></script>)中怎么用?
因为 <script setup></script> 没有 this,必须显式获取全局属性。推荐两种方式:
- 用
getCurrentInstance()(需从vue导入),再取proxy—— 注意:仅在组件已挂载后有效,onBeforeMount及之后才安全 - 更稳妥的方式:在
setup()外定义函数,或直接 import 工具函数(推荐)
如果坚持用全局挂载且在 <script setup></script> 中调用:
<script setup>
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
// ⚠️ instance 可能为 null(如服务端渲染或未挂载时),务必判空
const $formatPhone = instance?.proxy?.$formatPhone || ((v) => v)
console.log($formatPhone('13987654321')) // 139-8765-4321
</script>
比全局挂载更推荐的做法:用 composable 或工具函数
全局挂载看似方便,但实际带来几个隐性问题:
- 命名冲突风险(比如多个插件都挂了
$dateFormat) - TS 类型提示不完整(需手动声明
ComponentCustomProperties) - Tree-shaking 失效(所有方法全量打包)
- 单元测试难 mock
更现代、更可控的方式是:
- 把格式化逻辑写成独立函数,放在
utils/format.js - 在需要的地方
import { formatPhone } from '@/utils/format' - 模板中配合
v-bind或计算属性使用(避免模板中写复杂逻辑)
例如:
// utils/format.js
export const formatPhone = (phone) => {
if (!phone || String(phone).length !== 11) return ''
return String(phone).replace(/(\d{3})(\d{4})(\d{4})/, '$1-$2-$3')
}
<script setup>
import { formatPhone } from '@/utils/format'
const phone = ref('13812345678')
const formatted = computed(() => formatPhone(phone.value))
</script>
<template>
<view>{{ formatted }}</view>
</template>
这种写法类型安全、可测试、易复用,也更容易做按需导入和压缩。
真正要注意的不是“怎么挂”,而是挂了之后是否容易维护、是否干扰类型系统、是否让团队协作变模糊——这些点比语法能不能跑通更关键。


















