前端如何在表单中默认隐藏用户敏感信息?

瑞芳🍀 阅读 46

我在做一个用户资料编辑页,表单里有手机号和身份证号这些字段。现在页面加载时会直接显示完整信息,但产品要求默认只显示部分脱敏内容(比如 138****1234),用户点击“编辑”才显示完整值。我试过在 Vue 里用计算属性处理,但一提交表单就出问题,因为实际要传的是原始数据。

目前我是这样处理显示的:

computed: {
  maskedPhone() {
    return this.user.phone.replace(/(d{3})d{4}(d{4})/, '$1****$2');
  }
}

但提交时得确保发的是 this.user.phone 而不是脱敏后的值。有没有更安全又不容易出错的做法?担心以后加新字段会漏掉逻辑。

我来解答 赞 7 收藏
二维码
手机扫码查看
2 条解答
端木艺童
这个问题其实Vue官方文档在表单处理部分提到过类似的场景。最稳妥的做法是用两个数据源:一个存原始数据(用来提交),一个存脱敏后的展示数据。

按照规范,建议这么改:
1. 保留原始数据 user.phone 不动
2. 在data里加个 displayPhone 专门用来显示
3. 初始化时把脱敏数据赋给 displayPhone
4. 提交时直接用原始数据

代码大概长这样:

data() {
return {
user: { phone: '13812341234' },
displayPhone: '',
isEditing: false
}
},
created() {
this.displayPhone = this.maskPhone(this.user.phone)
},
methods: {
maskPhone(num) {
return num.replace(/(d{3})d{4}(d{4})/, '$1****$2')
},
toggleEdit() {
this.isEditing = !this.isEditing
this.displayPhone = this.isEditing
? this.user.phone
: this.maskPhone(this.user.phone)
}
}


这样有几个好处:
1. 原始数据永远不会被污染
2. 模板里直接用 displayPhone 展示
3. 提交时还是用 user.phone 原值
4. 加新字段时套用相同模式就行

我上次做类似功能时也踩过这个坑,后来发现这种分离关注点的方式最不容易出幺蛾子。
点赞
2026-03-07 09:02
设计师志丹
这个问题我之前也踩过坑,核心就是别把「显示用的脱敏值」和「实际提交的原始值」混在一个字段里,容易乱套。

我一般这么处理:
表单里用两个字段,一个存原始数据(比如 user.phone),一个专门用于展示(比如 displayPhone),两者分开维护,提交时只用原始字段。

具体做法:

页面初始化时,从接口拿到 user 后,直接存原始值:user.phone = '13812341234'
然后 displayPhone 单独用一个计算属性或响应式变量来生成脱敏后的字符串,比如:

displayPhone = computed(() => maskPhone(user.phone))

这样你输入框绑定的时候就用 displayPhone,但监听输入变化时别直接改 displayPhone,而是改 user.phone,然后 displayPhone 自动更新。
比如这样:

<input v-model="displayPhone" @input="onPhoneInput" />


onPhoneInput(e) {
// 过滤掉非数字字符,避免用户输奇怪的东西
const raw = e.target.value.replace(/D/g, '')
// 限制长度,身份证手机号一般有固定位数
if (raw.length <= 11) {
this.user.phone = raw
}
}


然后 displayPhone 的逻辑:

get displayPhone() {
return maskPhone(this.user.phone || '')
}


maskPhone 可以自己写个通用函数,比如:

function maskPhone(phone) {
if (!phone || phone.length < 7) return phone
return phone.replace(/(d{3})d{4}(d{4})/, '$1****$2')
}


重点是:输入框永远只绑定 displayPhone,但数据模型永远用 user.phone,提交时直接传 user.phone 就行,完全不用管脱敏的事。

另外如果你用的是表单组件库(比如 Element Plus、Ant Design Vue),可以考虑用 v-model:custom-value 自定义 v-model,把 displayPhone 封装进一个组件里,这样整个项目复用起来更省心。

如果字段多的话,建议写个通用的 useMaskedField(initialValue) 的 composable,里面管理原始值和 display 值,避免重复写逻辑。

希望能帮到你
点赞 3
2026-02-23 20:01