uni-app弹窗应避免v-model,改用show prop + @close事件;遮罩层需平台差异化处理滚动穿透;动画推荐uni.createAnimation;尺寸统一用rpx;z-index在App端需设高值;全面屏需适配safe-area-inset-bottom。
uni-app里用v-model控制弹窗显隐行不通
因为uni-app的v-model在自定义组件中默认绑定的是value prop 和 input事件,但弹窗组件通常不需要“双向输入值”,强行套用反而导致状态不同步、关闭后仍触发打开逻辑。
- 正确做法是只用一个
showprop(布尔值) +@close事件,由父组件控制显隐 - 子组件内部不维护
show状态,避免父子双源更新冲突 - 如果用了
v-model又没重写model选项,关闭时$emit('input', false)可能被忽略,尤其在H5平台表现不稳定
遮罩层点击穿透问题:catchtouchmove不是万能的
很多人加catchtouchmove阻止滚动,却忘了它只在微信小程序有效,在App和H5上完全不生效,结果遮罩下内容还能滚动或点中按钮。
-
App平台需额外设置style="position: fixed; top: 0; left: 0; width: 100%; height: 100%;"并确保z-index高于其他内容 -
H5要加pointer-events: none到body滚动区域,或用document.body.style.overflow = 'hidden'临时禁用滚动 - 遮罩层本身必须设
pointer-events: auto,否则点击无法触发关闭
动画卡顿或闪现:别直接用transition组件
uni-app的<transition>在App端(尤其是iOS)对opacity和transform支持不一致,常出现首帧闪白、动画跳过、关闭后DOM残留等问题。
- 推荐用
uni.createAnimation手动控制,兼容性更好,且可精确控制timingFunction - 动画起始态建议设为
opacity: 0; transform: scale(0.95),比纯透明更自然 - 务必在
animationend回调里uni.hideToast()或removeChild,否则App端可能内存泄漏
跨平台样式差异:px单位在App端会放大
uni-app编译到App时,px默认按设备物理像素处理,不像H5或小程序走rpx缩放,结果弹窗边框粗得离谱、文字挤成一团。
- 所有尺寸一律用
rpx,包括border-width、padding、font-size - 如果必须用
px(比如图标字体),得加平台判断:/* #ifdef APP-PLUS */ border-width: 1px; /* #endif */ -
z-index在App端数值要远大于H5(例如设9999),否则可能被原生导航栏盖住
最麻烦的其实是iPhone全面屏底部安全区——弹窗底部按钮容易被系统手势条挡住,得用env(safe-area-inset-bottom)做兜底适配,这个点很多人上线后才踩到。










