h5端需手动实现hideemail过滤器:先校验空值和字符串类型,再按@分割,账号长度≤2时原样返回,≥3时保留首尾字符并隐藏中间,域名不脱敏,确保兼容各种邮箱格式。

uni-app 里没有内置邮箱脱敏过滤器,得自己写一个通用的 hideEmail,但要注意:它只在 H5 端生效,小程序和 App 端根本不会执行——别把逻辑堆在模板里,否则真机上邮箱原样显示,毫无脱敏效果。
怎么写一个靠谱的 hideEmail 过滤器(仅限 H5)
邮箱脱敏不是简单截取前 2 位 + “***” + 后缀,得按 @ 分割、保留首尾字符、隐藏中间部分,还要兼容各种长度(如 a@b.com、test123@test.co.uk)。常见错误是直接用 substr(0, 2),结果 ab@cd.com 变成 ab***cd.com,漏掉 @ 前真实长度判断。
- 必须先用
.split('@')拆分账号和域名两段 - 账号部分长度 ≤ 2 时(如
a@、ab@),不隐藏,直接返回原账号 - 账号长度 ≥ 3 时:保留首字符 +
'*'.repeat(len - 2)+ 尾字符 - 域名部分不做脱敏,原样拼回,确保邮箱格式可读(如
t***t@gmail.com) - 务必加空值防护:
if (!value || typeof value !== 'string') return ''
示例实现(放在 @/common/filters/index.js,并在 main.js 中注册):
Vue.filter('hideEmail', function(value) {
if (!value || typeof value !== 'string') return ''
const parts = value.split('@')
if (parts.length !== 2) return value
const [account, domain] = parts
const len = account.length
if (len <h3>为什么小程序里 {{ email | hideEmail }} 完全没反应</h3><p>这不是你代码写错了,而是 uni-app 编译机制决定的:小程序端(微信/支付宝/字节等)压根不解析 <code>|</code> 管道语法,<code>Vue.filter</code> 注册的函数根本进不到小程序 JS 上下文里。现象是 H5 正常,小程序真机或开发者工具里邮箱原样显示,控制台也无报错。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2488" title="uni-app"><img
src="https://img.php.cn/upload/manual/001/431/639/6a6029e0c4cd4231.png" alt="uni-app" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2488" title="uni-app" class="overflowclass">uni-app</a>
<p class="overflowclass">uni-app 是基于 Vue 的跨端开发框架,适合开发 H5、App、小程序、鸿蒙和多端业务应用。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2488" title="uni-app" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
- 检查方式:在小程序端
console.log(Vue.options.filters),会发现是空对象 - 别指望
easycom或pages.json配置能修复——这是底层渲染引擎限制,非配置问题 - 哪怕你升级到 uni-app 3.x(Vue 3),过滤器 API 已被官方移除,H5 也不再支持
跨端真正能用的邮箱脱敏方案
放弃 Vue.filter,改用纯函数封装 + 显式调用,所有平台行为一致。
- 在
@/utils/filters.js导出函数:export const hideEmail = (email) => { if (!email || typeof email !== 'string') return '' const parts = email.split('@') if (parts.length !== 2) return email const [account, domain] = parts const len = account.length if (len - 页面中使用:
— 展示态:直接在computed或setup里调用,如const maskedEmail = hideEmail(userInfo.email)
— 列表渲染:在v-for内联调用(注意性能,避免复杂正则)
— 表单编辑态:绝不调用该函数处理原始数据,只用于展示 - 如果需响应式更新(如用户改邮箱后实时脱敏),用
computed包一层,不要在@input里手动改原始字段
v-model 和邮箱脱敏绝对不能混用
输入框绑定 v-model="userInfo.email" 时,千万别在模板里同时写 {{ userInfo.email | hideEmail }} 或 :placeholder="userInfo.email | hideEmail"。用户一输就会看到脱敏后的中间状态(比如刚打 t,显示 t***t@),体验错乱且不可逆。
- 编辑态:永远用原始
userInfo.email,不经过任何脱敏 - 展示态:才用
hideEmail(userInfo.email)或计算属性 - 禁止在
@input里调用脱敏函数去覆盖原始值——这破坏双向绑定,也违背数据源单一原则
最易被忽略的是:脱敏逻辑一旦写进模板管道,就等于默认它跨端可用;而实际上,它只在 H5 生效,其他端静默失效——这种“半生效”状态比直接报错更难排查。









