uni-app中手机号脱敏过滤器需在filters/index.js定义,用正则/^(\d{3})\d{4}(\d{4})$/精确匹配11位并替换中间四位,须加空值及类型判断(如!phone || typeof phone!=='string'),返回前转字符串;Vue2用Vue.filter注册,Vue3需改用自定义hook或computed封装。

uni-app 里怎么写手机号脱敏过滤器
直接在 filters/index.js 里定义一个函数,用正则替换中间四位即可。注意别漏掉对非 11 位字符串的兜底处理,否则空值或错误格式会报错或返回异常结果。
- 推荐正则:
/^(\d{3})\d{4}(\d{4})$/—— 精确匹配 11 位手机号,只脱敏中间段 - 不建议用
/(\d{3})\d{4}(\d{4})/(无锚点)—— 会误匹配长数字串里的子串,比如身份证号 - 必须加判断:
if (!phone || typeof phone !== 'string') return phone,防止传null、undefined或数字类型时.replace()报错 - 返回值统一用字符串:
String(phone).replace(...),避免 number 类型调用失败
在 Vue2 和 Vue3 的 uni-app 项目中如何注册和使用
Vue2 项目直接挂载到 Vue.filter;Vue3(尤其是 setup 语法糖)不能用全局 filter,得改用自定义 hook 或 computed 封装。这点容易被忽略,真机运行时报 filter is not defined 就是这个原因。
- Vue2 写法:
Vue.filter('phoneHide', (phone) => { ... }),模板中{{ mobile | phoneHide }} - Vue3 写法:导出一个函数
export const usePhoneHide = (phone) => computed(() => {...}),在页面里const hidden = usePhoneHide(mobileRef) - 如果用
uni-app的u-text组件,直接写,不用手写过滤器
为什么 u-text 的 mode="phone" 有时不生效
因为 u-text 的脱敏逻辑依赖内部判断:只有当 text 是纯数字字符串且长度为 11 位时才触发脱敏。传了带空格、括号、+86 前缀的号码,或者用了响应式 ref 但初始值为空,都会跳过处理。
- 常见错误:
text="+86 15700002232"→ 不脱敏;text="157-0000-2232"→ 不脱敏 - 正确做法:传之前先清洗:
mobile.replace(/[^0-9]/g, '') - 响应式场景下,确保
text绑定的是已清洗后的值,而不是原始输入框的原始内容 -
u-text不支持自定义脱敏位数(比如想隐藏后四位),这种需求必须手写正则
脱敏后点击复制或唤起拨号,会不会泄露原号码
不会。脱敏只是渲染层处理,v-model、:text 绑定的仍是原始值,点击拨号或复制操作读取的都是原始手机号。但要注意:如果用 u-text + click-to-call 功能,得确认它内部是否做了额外截断 —— 目前主流版本(如 uView 3.2+)没做,仍用原始值。
- 验证方式:在控制台打印
event.target.innerText(显示 ****)和data.mobile(显示完整号)对比 - 安全边界:脱敏仅作用于 UI 层,业务逻辑、API 请求、本地存储仍需确保用原始值,不要误把脱敏后字符串发给后端
- 特别提醒:某些自定义组件封装了「点击复制」功能,若内部用了
innerText而非绑定数据,就会复制 **** —— 这类 bug 必须检查组件源码或重写逻辑
脱敏本身很简单,真正容易出问题的是上下文:数据来源是否干净、框架版本是否支持、交互动作是否误读渲染内容。别只盯着正则写对没对,先看它跑在哪一层、被谁消费。










