应区分输入态、展示态、校验态:输入态用@input实时脱敏并保留rawIdCard原始值,支持15/18位及X结尾;展示态用filter全量处理并兜底空值异常。

直接用 idCardMask 这类自定义过滤器就行,但别只写个正则替换就完事——真实场景下要区分输入态、展示态、校验态,否则会把用户正在输的号码也遮掉,或者在表单提交时传错值。
输入框里实时遮掩(v-model + input 事件)
用户边输边看,前6位和后4位可见,中间用 * 替代。关键点是不能影响原始值存储,也不能干扰光标位置。
- 用
@input拦截输入,对v-model绑定的变量做“视图层脱敏”,但保留原始值在另一个字段(比如rawIdCard) - 正则别用
/\d{18}/粗暴匹配,得支持边输边处理:15位旧证、18位新证、带X结尾都要兼容 - 示例逻辑:
const maskIdCard = (val) => val.replace(/^(\d{6})(\d+)(\w{4})$/, '$1******$3'),但必须加长度判断,否则输到第7位就全变成****** - 输不满18位时,只遮中间已输入部分,比如输到12位,应显示
110101**********而不是110101******
展示层静态遮掩(filter 或 computed)
用于详情页、列表页等只读场景,这时可以放心全量处理,但要注意空值和异常格式兜底。
- 推荐封装成
filters/idCard.js导出函数:export const idCardMask = (val) => { if (!val || typeof val !== 'string') return ''; const trimmed = val.trim(); if (trimmed.length - Vue 2 中可在模板用
{{ idCard | idCardMask }};Vue 3 + Composition API 建议用computed包一层,避免 filter 全局污染 - 别漏掉大小写 X 的处理:正则末尾用
\w或[0-9Xx],否则11010119900307271X会被截断
表单提交前校验与还原
遮掩只是视觉反馈,后端需要完整身份证号。最容易踩的坑是:把遮掩后的字符串当原始值提交了。
- 确保提交数据取的是未加工的
rawIdCard字段,而不是绑定在 input 上那个被遮掩过的displayIdCard - 如果用了
v-model双向绑定到同一个字段,必须在提交前手动还原:先去掉 *,再校验格式(用你知识库里那个validateidcard函数) - 小程序真机调试时注意:iOS 输入法自动补全可能触发两次
@input,导致遮掩逻辑错乱,建议加防抖或比对前后值再执行
真正麻烦的不是怎么遮,而是遮完之后怎么保证“看起来对、输起来顺、交上去准”——三个状态混在一起时,一个变量撑不住,得拆开管。


















