ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Vant Weapp Popup 弹出层组件完全指南:属性、事件、动画与滚动穿透解决方案

Vant Weapp Popup 弹出层组件完全指南:属性、事件、动画与滚动穿透解决方案 Vant Weapp Popup 弹出层组件完全指南属性、事件、动画与滚动穿透解决方案【免费下载链接】vant-weapp轻量、可靠的小程序 UI 组件库项目地址: https://gitcode.com/gh_mirrors/va/vant-weappPopup 弹出层是 Vant Weapp 小程序组件库中最基础也最常用的容器组件之一用于承载弹窗、底部操作栏、信息提示、选择面板等各类浮层内容并原生支持多个弹出层叠加展示。本文以 packages/popup/README.md 为骨架结合组件源码packages/popup/index.ts、packages/popup/index.wxml、packages/popup/popup.wxml、packages/popup/index.less与配套测试系统讲解它的引入方式、全部 Props/Events、四种弹出位置、关闭图标、圆角弹窗、安全区适配、动画原理以及滚动穿透的完整解决方案读完即可在真实小程序项目中熟练落地使用。组件介绍Popup 弹出层本质是一个固定定位position: fixed的浮层容器可用来展示任意自定义内容。它具备三个核心特性可控显示通过show属性布尔值控制弹出与收起可叠加同一页面可同时存在多个 Popup 实例配合z-index实现层级管理动画内置进入/离开均带有过渡动画且动画时长可配置。从 packages/popup/index.ts 的实现看Popup 组件通过VantComponent注册并混入了transition(false)过渡动画 Behaviorpackages/mixins/transition.ts因此它的显示隐藏、动画生命周期与 Transition 组件保持同一套机制详见下文动画与事件一节。引入组件在app.json全局或页面级index.json中声明组件即可在对应作用域使用usingComponents: { van-popup: vant/weapp/popup/index }引入后在 WXML 中直接书写van-popup标签。完整的快速上手流程可参考 docs/markdown/quickstart.md 中的组件引入章节。组件本身依赖van-overlay遮罩层、van-icon关闭图标与van-transition等内部组件引入 Popup 时无需额外手动注册这些依赖它们随组件包一并可用。代码演示基础用法通过show属性控制弹出层是否展示bind:close在弹出层关闭时触发用于同步页面数据van-cell title展示弹出层 is-link bind:clickshowPopup / van-popup show{{ show }} bind:closeonClose内容/van-popupPage({ data: { show: false, }, showPopup() { this.setData({ show: true }); }, onClose() { this.setData({ show: false }); }, });要点show从false变为true时组件执行进入动画从true变为false时执行离开动画动画结束后隐藏节点点击遮罩层默认会触发close事件可通过close-on-click-overlay关闭此行为因此需要在事件回调中把show同步回false形成完整的关闭-回写闭环组件根节点默认不带内边距可在标签内部直接书写内容或通过custom-style传入内边距等样式示例工程中即使用了custom-stylepadding: 30px 50px见 packages/popup/demo/index.wxml。弹出位置通过position属性设置弹出位置默认居中弹出可取值center、top、bottom、left、rightvan-popup show{{ show }} positiontop custom-styleheight: 20%; bind:closeonClose /位置样式在 packages/popup/index.less 中定义centertop: 50%; left: 50%; transform: translate3d(-50%, -50%, 0)居中定位top/bottom占满整行宽度width: 100%分别贴顶部、贴底部left/right垂直居中贴左、贴右高度通常需配合custom-style指定。注意弹出层宽度/高度默认由内容撑开居中弹窗或整行/整列top/bottom 为width: 100%。像height: 20%、width: 20%; height: 100%这类尺寸需要配合custom-style显式指定示例工程中四个方向的完整写法参见 packages/popup/demo/index.wxml。由于position同时驱动过渡动画的方向类名van-top-*、van-bottom-*等index.ts中为position注册了observeClass观察器动态修改位置时会同步更新动画 classpackages/popup/index.ts。关闭图标设置closeable属性后弹出层右上角会显示关闭图标close-icon可自定义图标名称或图片链接默认crossclose-icon-position可调整图标位置van-popup show{{ show }} closeable positionbottom custom-styleheight: 20% bind:closeonClose / !-- 自定义图标 -- van-popup show{{ show }} closeable close-iconclose positionbottom custom-styleheight: 20% bind:closeonClose / !-- 图标位置 -- van-popup show{{ show }} closeable close-icon-positiontop-left positionbottom custom-styleheight: 20% bind:closeonClose /实现细节关闭图标是组件内部渲染的van-iconname{{ closeIcon }}支持内置图标名或自定义图片链接packages/popup/popup.wxml图标位置通过修饰类van-popup__close-icon--top-left / top-right / bottom-left / bottom-right控制四角间距统一使用 CSS 变量--popup-close-icon-margin默认 16px见 packages/popup/index.less点击图标触发onClickCloseIcon直接$emit(close)通知页面关闭packages/popup/index.ts图标的颜色、字号、层级均可通过--popup-close-icon-color、--popup-close-icon-size、--popup-close-icon-z-index等 CSS 变量覆盖默认值见 packages/common/style/var.less。圆角弹窗设置round属性后弹窗会根据弹出位置自动添加对应方向的圆角van-popup show{{ show }} round positionbottom custom-styleheight: 20% bind:closeonClose /圆角逻辑位于 packages/popup/index.lesscenter四角统一圆角top仅底部两角圆角bottom仅顶部两角圆角最常见的底部圆角弹窗形态left/right对应侧的两角圆角。圆角半径使用 CSS 变量--popup-round-border-radius控制默认 16pxpackages/common/style/var.less。禁止滚动穿透使用组件时会发现当弹窗内容滚动到底部后继续划动会连带滚动底层页面这就是滚动穿透。组件提供lock-scroll属性默认true处理部分滚动穿透问题。其实现位于遮罩层当lock-scroll为真时遮罩节点绑定catch:touchmove阻止触摸事件冒泡packages/overlay/overlay.wxml从而阻止遮罩层区域内的滚动穿透。但受小程序平台自身限制弹窗内容区域仍可能出现滚动穿透。官方推荐一个更彻底的方案——使用page-meta组件动态修改页面样式!-- page-meta 只能是页面内的第一个节点 -- page-meta page-style{{ show ? overflow: hidden; : }} / van-popup show{{ show }} catch:touchstart /方案说明当小程序基础库最低版本在2.9.0 以上时即可使用 page-meta 组件page-meta必须是页面内的第一个节点弹窗打开时通过page-style给页面根节点加overflow: hidden从根上禁用页面滚动关闭后恢复为空字符串配合van-popup show{{ show }} catch:touchstart /捕获弹出层上的触摸起始事件双重保险。APIProps完整参数表如下其中标注版本号的参数v1.7.3、v1.10.14为后续版本新增能力参数说明类型默认值show是否显示弹出层booleanfalsez-indexz-index 层级number100overlay是否显示遮罩层booleantrueposition弹出位置可选值为topbottomrightleftstringcenterduration动画时长单位为毫秒number | object300round是否显示圆角booleanfalsecustom-style自定义弹出层样式stringoverlay-style自定义遮罩层样式stringclose-on-click-overlay是否在点击遮罩层后关闭booleantruecloseable是否显示关闭图标booleanfalseclose-icon关闭图标名称或图片链接stringcrossclose-icon-position关闭图标位置可选值为top-leftbottom-leftbottom-rightstringtop-rightsafe-area-inset-bottom是否为 iPhoneX 留出底部安全距离booleantruesafe-area-inset-top是否留出顶部安全距离状态栏高度booleanfalsesafe-area-tab-bar是否留出底部 tabbar 安全距离在使用 tabbar 组件 小程序自定义 tabbar 时popup 组件层级无法盖住 tabbarbooleanfalselock-scrollv1.7.3是否锁定背景滚动booleantrueroot-portalv1.10.14是否从页面中脱离出来用于解决各种 fixed 失效问题微信基础库 2.25.2booleanfalse各参数的源码落点packages/popup/index.ts与行为细节show / duration / name这三个属性来自混入的transitionBehaviorpackages/mixins/transition.ts其中duration类型为null即不限制既可以是数字如300也可以是对象{ enter, leave }分别指定进入/离开时长position / transition非文档公开属性组件额外支持transition属性覆盖动画名称。observeClass观察器逻辑为name transition || position即默认以position作为动画名若transition传入none则动画时长会被临时置 0原时长保存在originDuration恢复时还原实现无动画效果packages/popup/index.tsz-index默认100同时透传给内部遮罩层与弹出层节点packages/popup/index.wxs多弹窗叠加时通过增大该值控制谁在上层safe-area-tab-bar开启后底部弹出的 Popup 会把bottom抬高到 tabbar 高度之上CSS 变量--tabbar-height默认 50px见 packages/popup/index.less 与 packages/common/style/var.less用于解决自定义 tabbar 场景下弹层被盖住的问题safe-area-inset-bottom / safe-area-inset-top分别通过env(safe-area-inset-bottom)、env(safe-area-inset-top)计算安全区packages/popup/index.less前者默认开启适用于底部弹出的操作面板root-portal开启后弹层内容会渲染进root-portal节点脱离页面 DOM规避各种fixed失效问题如被transform祖先节点影响需要微信基础库 2.25.2。模板中通过wx:if{{ rootPortal }}在根节点渲染与普通渲染两条分支间切换packages/popup/index.wxml。Events事件名说明参数bind:close关闭弹出层时触发-bind:click-overlay点击遮罩层时触发-bind:before-enter进入前触发-bind:enter进入中触发-bind:after-enter进入后触发-bind:before-leave离开前触发-bind:leave离开中触发-bind:after-leave离开后触发-事件触发链路源码可查click-overlay / close点击遮罩层时onClickOverlay先$emit(click-overlay)若closeOnClickOverlay为真再$emit(close)packages/popup/index.ts。遮罩的点击事件由内部van-overlay的bind:click转发packages/popup/index.wxmlclose除点击遮罩层外点击关闭图标onClickCloseIcon同样触发closepackages/popup/index.tsbefore-enter / enter / after-enter / before-leave / leave / after-leave全部由transitionBehavior 在动画各阶段$emit发出packages/mixins/transition.ts。其中进入流程为before-enter → enter → after-enter离开流程为before-leave → leave → after-leave动画结束后若show仍为假组件将display置为false隐藏节点。外部样式类类名说明custom-class根节点样式类custom-class会附加到弹出层根节点packages/popup/popup.wxml。此外从组件注册的classes列表packages/popup/index.ts可以看到它内部还支持enter-class、enter-active-class、enter-to-class、leave-class、leave-active-class、leave-to-class以及close-icon-class这 7 个过渡动画阶段类名与关闭图标类名可在使用 Transition 组件时按需传入实现更细粒度的动画与图标自定义。动画机制与叠加弹窗Popup 的进入/离开动画由transitionBehaviorpackages/mixins/transition.ts统一驱动show变为true时执行enureEnter通过两帧requestAnimationFrame依次设置enter与enter-to过渡类名配合 CSStransition完成动画show变为false时执行enureLeave等待进入动画完成后再执行离开动画动画时长结束后触发onTransitionEnd并隐藏节点动画时长取自duration数字或{ enter, leave }对象过渡类名由name默认取position生成如van-bottom-enter、van-bottom-leave-toCSS 定义见 packages/popup/index.less。由于position直接映射动画方向top/bottom上下滑入、left/right左右滑入、center淡入、scale缩放淡入因此同一个 Popup 只需切换position出入动画会自动跟随方向变化。关于支持多个弹出层叠加展示每个van-popup都是独立实例、独立管理自身show与动画状态且默认z-index: 100可逐层调大。实际项目中常见的底部操作面板 二次确认弹窗叠加场景即为两个 Popup 实例同时存在、各自受控。测试与示例工程仓库为 Popup 提供了完整的演示与测试支撑示例页面packages/popup/demo/index.wxml 覆盖基础用法、四种弹出位置、关闭图标默认/自定义/位置、圆角弹窗共 9 个场景配套逻辑见 packages/popup/demo/index.ts各场景通过toggle(type, show)统一管理show状态快照测试packages/popup/test/demo.spec.ts 使用miniprogram-simulate加载 demo 并断言渲染结果与快照一致快照见 packages/popup/test/snapshots/demo.spec.ts.snap可在修改组件后运行测试验证渲染不回归已编译产物小程序可直接使用的构建结果位于 lib/popup/index.js、lib/popup/index.wxml、lib/popup/index.wxss 等文件vant/weapp/popup/index即指向该产物目录。样式定制除了custom-style与overlay-style两个实例级样式入口Popup 的视觉细节几乎全部可以通过 CSS 变量覆盖适合在全局或页面级主题中统一调整CSS 变量默认值作用--popup-background-colorwhite#fff弹出层背景色--popup-round-border-radius16px圆角弹窗的圆角半径--popup-close-icon-size18px关闭图标字号--popup-close-icon-colorgray-6#969799关闭图标颜色--popup-close-icon-margin16px关闭图标与边缘的间距--popup-close-icon-z-index1关闭图标层级--tabbar-height50pxsafe-area-tab-bar场景下弹层抬升高度以上默认值均可在 packages/common/style/var.less 与 packages/popup/index.less 中核对。组件内样式统一采用var(--xxx, 默认值)的兜底写法未定义变量时自动回退到默认值因此按需覆盖即可不会影响其他组件。常见问题点击遮罩层不关闭检查是否误设close-on-click-overlay{{ false }}同时注意close事件只负责通知仍需在页面回调中把show置回false。弹层被自定义 tabbar 盖住使用底部 tabbar 组件且为自定义 tabbar 时设置safe-area-tab-bar为true弹层会自动抬升到--tabbar-height默认 50px之上。fixed 定位失效弹出层显示位置错乱当页面或祖先节点存在transform、filter等属性导致fixed失效时开启root-portal微信基础库 2.25.2让弹层脱离页面渲染。弹窗内容区域滚动穿透无法解决lock-scroll只能拦截遮罩层区域的滚动穿透内容区域请采用官方推荐的page-meta基础库 2.9.0catch:touchstart组合方案。需要无动画弹出通过内部transition属性传入none组件会临时将动画时长置 0实现瞬时显示/隐藏。【免费下载链接】vant-weapp轻量、可靠的小程序 UI 组件库项目地址: https://gitcode.com/gh_mirrors/va/vant-weapp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表