Uni-app / Vue 中身份证号脱敏的正确实现
一、业务背景说明
在医疗、政务、金融等小程序场景中,身份证号属于强隐私数据。常见的产品要求是:
- 页面展示时 不能明文显示完整身份证号
- 通常规则为:前 6 位 + 后 4 位可见,中间用
*替代 - 点击、提交、接口交互时仍使用原始完整数据
因此,前端的核心任务只有一个:
展示层脱敏,不影响原始数据结构
本文基于你当前的 uni-app + Vue2 项目,不做任何封装,只讲清楚「为什么错」「应该怎么写」「每种写法适合什么场景」。
二、最容易犯的错误
错误 1:直接在模板里对非字符串使用 slice
vue
{{ doctor.id_card_no.slice(0,6) }}
问题原因
- 后端返回的
id_card_no可能是 number slice只存在于String / Array
运行时就会报错:
TypeError: e.slice is not a function
错误 2:把"带参数的函数"写进 computed
js
computed: {
maskIdCard(id) {
return id.slice(0,6) + '****' + id.slice(-4)
}
}
模板中使用:
vue
{{ maskIdCard(item.id_card_no) }}
问题原因(非常关键)
computed不是函数工具区computed本质是:基于响应式状态的属性- Vue 不会把它当成
methods处理
最终就会报错:
TypeError: e.maskIdCard is not a function
三、正确做法一:methods(最推荐、最直观)
methods 中定义脱敏函数
js
methods: {
maskIdCard(id) {
// 1. 空值保护
if (id === null || id === undefined) return '';
// 2. 强制转字符串(关键)
const str = String(id);
// 3. 长度不足直接返回
if (str.length <= 8) return str;
// 4. 身份证标准脱敏规则
return (
str.slice(0, 6) +
'*'.repeat(str.length - 10) +
str.slice(-4)
);
}
}
模板中直接调用
vue
<view class="name1">
{{ maskIdCard(doctor.id_card_no) }}
</view>
优点
- 写法直观,符合直觉
- 支持传参
- 不依赖响应式缓存
- 非常适合「工具函数」
结论:带参数的展示逻辑 = methods
四、正确做法二:computed(仅限"当前就诊人")
如果页面只展示 一个固定对象 (例如 selectedPatient),可以用 computed。
computed 写法
js
computed: {
maskedIdCard() {
const id = this.selectedPatient?.id_card_no;
if (!id) return '';
const str = String(id);
if (str.length <= 8) return str;
return (
str.slice(0, 6) +
'*'.repeat(str.length - 10) +
str.slice(-4)
);
}
}
模板使用
vue
<view class="name1">
{{ maskedIdCard }}
</view>
限制说明
- 不能传参
- 不适合列表
- 只适合「单对象展示」
五、列表场景为什么一定要用 methods
真实场景:
vue
<pationsCard
v-for="item in pationsList"
:cardId="maskIdCard(item.id_card_no)"
/>
原因只有一句话:
computed 不能根据不同 item 动态计算
列表中:
- 每一项都是不同身份证号
- 每次渲染都需要传参
只能用 methods
六、最终推荐规范(非常重要)
| 场景 | 正确位置 |
|---|---|
| 列表身份证脱敏 | methods |
| 单个当前用户展示 | computed |
| 传参的展示逻辑 | methods |
| 工具型字符串处理 | methods |
七、一句话总结
在 Vue / Uni-app 中,computed 用于"状态派生值" ,methods 用于"带参数的展示逻辑" 。身份证号脱敏本质是字符串处理工具函数,在列表与组件参数中使用时,只能也必须写在 methods 中。