Vue组件中手机号脱敏显示失效了怎么办?

东方朝炜 阅读 43

在用户信息展示页面需要脱敏显示手机号,写了计算属性处理,但发现像13812345678这样的号码显示成138****5678是对的,可当输入1391234567这种11位以外的号码时就直接返回原值了,该怎么处理这种情况?


<template>
  <p>电话:{{ formatPhone(user.phone) }}</p>
</template>

<script>
export default {
  data() {
    return {
      user: { phone: '13812345678' }
    }
  },
  methods: {
    formatPhone(phone) {
      return phone.replace(/(d{3})d{4}(d{4})/, '$1****$2')
    }
  }
}
</script>

我试过在正则里加了?量词变成/(\d{3})\d{0,4}(\d{4})/,但发现1391234567会变成139**34567,中间位数不对了。有没有更稳妥的脱敏实现方式?

我来解答 赞 19 收藏
二维码
手机扫码查看
2 条解答
百里殿洁
这种手机号脱敏确实要处理不同位数的情况,你那个正则的问题在于d{0,4}匹配太灵活了。改一下就行:

formatPhone(phone) {
if (!phone || phone.length < 7) return phone // 太短的号码直接返回
const start = phone.substr(0, 3)
const end = phone.substr(phone.length - 4)
return ${start}****${end}
}


这样处理:
1. 取前3位和后4位,中间固定用4个星号
2. 不足7位的原样返回(比如固话)
3. 不用正则,直接字符串操作更稳

测试用例:
13812345678 → 138**5678
1391234567 → 139**4567
12345 → 12345
点赞
2026-03-06 08:22
欧阳一涵
你这个正则问题出在没正确匹配数字字符,d写成了d,JS里根本不会识别,所以replace压根没生效。另外对非11位的手机号直接替换中间部分也不合理。

通用的做法是先校验是否为合法手机号,再按规则脱敏。对于不合规的号码可以选择原样显示或统一处理。

正确的实现应该是:

formatPhone(phone) {
// 转字符串并去空格
const str = String(phone).trim()
// 匹配以1开头的11位数字
if (/^1d{10}$/.test(str)) {
return str.replace(/(d{3})d{4}(d{4})/, '$1****$2')
}
// 非法格式返回原值(也可返回打码占位符)
return str
}


这样13812345678正常脱敏成138****5678,而像1391234567这种10位的就不会被错误处理。如果你还想兼容带区号或国际号码,可以额外加逻辑判断长度和前缀,但一般国内业务用上面这个就够了。
点赞 12
2026-02-12 06:01