更新记录
1.0.0(2026-02-21) 下载此版本
1.0.0(2026-02-21)
- 首次发布
- 支持 5 个弹出方向:top / bottom / center / left / right
- 支持 3 个类型别名:message / dialog / share,兼容 uni-popup 用法
- 纯 CSS transition 驱动动画,transitionend 回调 + setTimeout 兜底
- v-model:show 双向绑定,声明式 + 命令式双模式
- round 快捷圆角,根据方向自动计算圆角位置
- closeable 内置关闭图标,支持四角定位
- before-close 异步拦截关闭,支持 Promise / Boolean
- opened / closed 动画完成事件
- z-index 全局自增,多弹窗叠加层级正确
- 四方向手势滑动关闭,阈值可配
- 滚动穿透锁定(touchmove + H5 body overflow)
- CSS Variables 主题定制
- provide/inject 子组件通信
- Promise 化 API,open()/close() 返回 Promise
- 底部安全区自动适配
- ESC 键关闭(H5)
- keep-alive 支持
- Vue2 / Vue3 双兼容
- 全端兼容:H5、App、微信/支付宝/百度/抖音/QQ 小程序
平台兼容性
uni-app(4.0)
| Vue2 | Vue2插件版本 | Vue3 | Vue3插件版本 | Chrome | Chrome插件版本 | Safari | Safari插件版本 | app-vue | app-vue插件版本 | app-nvue | app-nvue插件版本 | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | 4.4 | 1.0.0 | 12 | 1.0.0 | - |
| 微信小程序 | 微信小程序插件版本 | 支付宝小程序 | 支付宝小程序插件版本 | 抖音小程序 | 抖音小程序插件版本 | 百度小程序 | 百度小程序插件版本 | 快手小程序 | 快手小程序插件版本 | 京东小程序 | 京东小程序插件版本 | 鸿蒙元服务 | 鸿蒙元服务插件版本 | QQ小程序 | QQ小程序插件版本 | 飞书小程序 | 飞书小程序插件版本 | 小红书小程序 | 快应用-华为 | 快应用-华为插件版本 | 快应用-联盟 | 快应用-联盟插件版本 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | - | √ | 1.0.0 | √ | 1.0.0 |
其他
| 多语言 | 暗黑模式 | 宽屏模式 |
|---|---|---|
| × | × | √ |
ay-popup 高级弹出层
高性能 uni-app 弹出层组件,解决 uni-popup 核心痛点,全端兼容。
为什么选择 ay-popup
ay-popup 逐一解决这些痛点:
| 痛点 | uni-popup | ay-popup |
|---|---|---|
| 动画机制 | JS 驱动,易卡顿 | 纯 CSS transition,GPU 加速 |
| 动画回调 | 无 opened/closed 事件 | transitionend 精确回调 + setTimeout 兜底 |
| 多层叠加 | z-index 固定,层级错乱 | 全局自增 z-index,叠加不错乱 |
| 滚动穿透 | 部分平台未处理 | touchmove.stop.prevent + H5 body overflow 锁定 |
| 关闭控制 | 无拦截机制 | before-close 异步拦截,支持 Promise |
| 手势关闭 | 不支持 | 四方向手势滑动关闭 |
| 圆角处理 | 需手动计算 | round 一键圆角,根据方向自动计算 |
| 关闭图标 | 需自行实现 | closeable 内置,四角位置可配 |
| API 模式 | 仅命令式 | 命令式 + v-model:show 声明式双模式 |
| Promise | 不支持 | open()/close() 返回 Promise |
| 主题定制 | 困难 | CSS Variables 全面覆盖 |
| 子组件通信 | 不支持 | provide/inject 注入 |
| keep-alive | 未处理 | activated/deactivated 正确恢复状态 |
特性一览
- 纯 CSS transition 驱动动画,transitionend 精确回调 + setTimeout 兜底
- 5 个弹出方向:top / bottom / center / left / right
- 3 个类型别名:message(top) / dialog(center) / share(bottom),兼容 uni-popup 用法
- v-model:show 双向绑定,声明式 + 命令式双模式
- round 快捷圆角,根据方向自动计算圆角位置
- closeable 内置关闭图标,支持四角定位
- before-close 异步拦截关闭,支持 Promise / Boolean
- opened / closed 动画完成事件(区别于 open / close 立即事件)
- z-index 全局自增,多弹窗叠加层级正确
- 四方向手势滑动关闭,阈值可配
- 滚动穿透锁定(touchmove + H5 body overflow)
- CSS Variables 主题定制
- provide/inject 子组件通信
- Promise 化 API,open()/close() 均返回 Promise
- 底部安全区自动适配
- ESC 键关闭(H5)
- keep-alive 支持
- Vue2 / Vue3 双兼容
- 全端兼容:H5、App、微信/支付宝/百度/抖音/QQ 小程序
安装
在 HBuilderX 中,从插件市场导入即可使用,无需额外配置。
快速开始
命令式调用
<template>
<ay-popup ref="popup" type="bottom" round background="#fff">
<view style="padding: 40rpx;">
<text>底部弹窗内容</text>
<button @click="$refs.popup.close()">关闭</button>
</view>
</ay-popup>
<button @click="$refs.popup.open()">打开弹窗</button>
</template>
声明式调用(v-model)
<template>
<ay-popup v-model:show="visible" type="center" round>
<view style="padding: 40rpx;">
<text>居中弹窗</text>
<button @click="visible = false">关闭</button>
</view>
</ay-popup>
<button @click="visible = true">打开弹窗</button>
</template>
<script>
export default {
data() {
return { visible: false }
}
}
</script>
五个方向
<!-- 居中弹窗 -->
<ay-popup ref="center" type="center" round>
<view class="content">居中</view>
</ay-popup>
<!-- 底部弹窗 -->
<ay-popup ref="bottom" type="bottom" round background="#fff">
<view class="content">底部</view>
</ay-popup>
<!-- 顶部弹窗 -->
<ay-popup ref="top" type="top" round background="#fff">
<view class="content">顶部</view>
</ay-popup>
<!-- 左侧抽屉 -->
<ay-popup ref="left" type="left" background="#fff">
<view style="width: 500rpx; height: 100%; padding: 40rpx;">左侧</view>
</ay-popup>
<!-- 右侧抽屉 -->
<ay-popup ref="right" type="right" background="#fff">
<view style="width: 500rpx; height: 100%; padding: 40rpx;">右侧</view>
</ay-popup>
圆角模式
round 属性会根据弹出方向自动计算圆角位置,无需手动设置 border-radius。
<!-- 底部弹窗:左上 + 右上圆角 -->
<ay-popup type="bottom" round />
<!-- 顶部弹窗:左下 + 右下圆角 -->
<ay-popup type="top" round />
<!-- 居中弹窗:四角圆角 -->
<ay-popup type="center" round />
<!-- 左侧抽屉:右上 + 右下圆角 -->
<ay-popup type="left" round />
<!-- 也可以自定义圆角 -->
<ay-popup type="bottom" border-radius="20px 20px 0 0" />
关闭图标
<ay-popup type="bottom" round closeable>
<view style="padding: 60rpx 40rpx 40rpx;">
内置关闭图标,默认右上角
</view>
</ay-popup>
<!-- 自定义位置 -->
<ay-popup type="bottom" round closeable close-icon-position="top-left">
<view>关闭图标在左上角</view>
</ay-popup>
关闭拦截(before-close)
<ay-popup ref="popup" :before-close="onBeforeClose">
<view>关闭前会触发拦截</view>
</ay-popup>
<script>
export default {
methods: {
// 方式一:返回 Promise
onBeforeClose() {
return new Promise(resolve => {
// resolve(true) 允许关闭,resolve(false) 阻止关闭
uni.showModal({
title: '确认关闭?',
success: res => resolve(res.confirm)
})
})
}
// 方式二:直接返回 Boolean
// onBeforeClose() { return false }
}
}
</script>
注意:H5 端如果
uni.showModal被 ay-popup 遮罩遮挡,建议用另一个 ay-popup 实例做确认弹窗,z-index 自增机制会确保它在最上层。
手势滑动关闭
<ay-popup type="bottom" round :swipe-close="true" :swipe-threshold="80">
<view style="min-height: 60vh; padding: 40rpx;">
向下拖拽超过 80px 自动关闭
</view>
</ay-popup>
支持四个方向的手势关闭:底部弹窗下滑、顶部弹窗上滑、左侧抽屉左滑、右侧抽屉右滑。
多层叠加
<ay-popup ref="layer1" type="center" round>
<view>
<text>第一层</text>
<button @click="$refs.layer2.open()">打开第二层</button>
</view>
</ay-popup>
<ay-popup ref="layer2" type="bottom" round closeable>
<view>第二层,z-index 自动高于第一层</view>
</ay-popup>
Promise API
// open() 在动画结束后 resolve
await this.$refs.popup.open()
console.log('弹窗已完全打开')
// close() 在动画结束后 resolve(受 before-close 拦截)
await this.$refs.popup.close()
console.log('弹窗已完全关闭')
自定义遮罩
<ay-popup
mask-background="rgba(0,0,0,0.7)"
overlay-class="my-overlay"
:overlay-style="{ backdropFilter: 'blur(4px)' }"
>
<view>自定义遮罩样式</view>
</ay-popup>
子组件通信
子组件可通过 inject 获取 ay-popup 实例,直接调用 close() 等方法。
export default {
inject: ['ayPopup'],
methods: {
handleConfirm() {
// 处理业务逻辑后关闭弹窗
this.ayPopup.close()
}
}
}
CSS Variables 主题定制
/* 在页面或全局样式中覆盖 */
page {
--ay-popup-bg: #fff; /* 内容区背景 */
--ay-popup-overlay-bg: rgba(0, 0, 0, 0.4); /* 遮罩背景 */
--ay-popup-round-radius: 32rpx; /* round 圆角大小 */
--ay-popup-timing: cubic-bezier(0.36, 0.66, 0.04, 1); /* 动画曲线 */
--ay-popup-close-size: 60rpx; /* 关闭图标区域大小 */
--ay-popup-close-font-size: 32rpx; /* 关闭图标字号 */
--ay-popup-close-color: #969799; /* 关闭图标颜色 */
}
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| show | Boolean | null | 配合 v-model:show 双向绑定 |
| type | String | center |
弹出方向:top / bottom / center / left / right,别名:message / dialog / share |
| duration | Number | 300 |
动画时长,单位 ms |
| animation | Boolean | true |
是否开启动画,设为 false 则立即显示/隐藏 |
| mask | Boolean | true |
是否显示遮罩 |
| maskClosable | Boolean | true |
点击遮罩是否关闭弹窗 |
| maskBackground | String | - | 遮罩背景色,默认取 CSS 变量 --ay-popup-overlay-bg |
| overlayClass | String | - | 自定义遮罩类名 |
| overlayStyle | Object | {} |
自定义遮罩样式对象 |
| background | String | - | 内容区背景色,默认取 CSS 变量 --ay-popup-bg |
| borderRadius | String | - | 自定义圆角值,优先级高于 round |
| round | Boolean | false |
快捷圆角,根据弹出方向自动计算 |
| closeable | Boolean | false |
是否显示关闭图标 |
| closeIconPosition | String | top-right |
关闭图标位置:top-right / top-left / bottom-right / bottom-left |
| safeArea | Boolean | true |
底部弹窗是否自动适配安全区 |
| swipeClose | Boolean | false |
是否开启手势滑动关闭 |
| swipeThreshold | Number | 80 |
手势关闭触发阈值,单位 px |
| lockScroll | Boolean | true |
是否锁定背景滚动 |
| customStyle | Object | {} |
自定义内容区样式对象 |
| beforeClose | Function | null |
关闭前拦截函数,返回 Promise<boolean> 或 false 阻止关闭 |
Methods
通过 ref 调用:
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
| open(direction?) | direction: 可选,弹出方向 | Promise |
打开弹窗,动画结束后 resolve |
| close() | - | Promise |
关闭弹窗,受 beforeClose 拦截,动画结束后 resolve |
| closeMask() | - | void |
运行时隐藏遮罩 |
| disableMask() | - | void |
运行时禁用遮罩点击关闭 |
Events
| 事件名 | 回调参数 | 说明 |
|---|---|---|
| update:show | boolean |
v-model:show 更新时触发 |
| change | { show: boolean, type: string } |
弹窗状态变化时触发 |
| maskClick | - | 点击遮罩时触发(无论是否关闭) |
| open | - | 弹窗开始打开时立即触发(动画开始前) |
| close | - | 弹窗开始关闭时立即触发(动画开始前) |
| opened | - | 打开动画结束后触发 |
| closed | - | 关闭动画结束后触发 |
CSS Variables
| 变量名 | 默认值 | 说明 |
|---|---|---|
--ay-popup-bg |
#fff |
内容区背景色 |
--ay-popup-overlay-bg |
rgba(0,0,0,0.4) |
遮罩背景色 |
--ay-popup-round-radius |
32rpx |
round 模式圆角大小 |
--ay-popup-timing |
cubic-bezier(0.36, 0.66, 0.04, 1) |
动画缓动曲线 |
--ay-popup-close-size |
60rpx |
关闭图标点击区域大小 |
--ay-popup-close-font-size |
32rpx |
关闭图标字号 |
--ay-popup-close-color |
#969799 |
关闭图标颜色 |
兼容性
| 平台 | 支持 |
|---|---|
| Vue2 | ✅ |
| Vue3 | ✅ |
| H5 (Chrome/Safari/Firefox/Edge) | ✅ |
| App (app-vue) | ✅ |
| 微信小程序 | ✅ |
| 支付宝小程序 | ✅ |
| 百度小程序 | ✅ |
| 抖音小程序 | ✅ |
| QQ小程序 | ✅ |
| app-nvue | 未测试 |
| 快手/京东/鸿蒙小程序 | 未测试 |
从 uni-popup 迁移
ay-popup 兼容 uni-popup 的 type 别名,迁移成本低:
| uni-popup | ay-popup | 说明 |
|---|---|---|
type="message" |
type="message" |
等同于 top |
type="dialog" |
type="dialog" |
等同于 center,自动禁用遮罩点击 |
type="share" |
type="share" |
等同于 bottom |
this.$refs.popup.open('top') |
this.$refs.popup.open('top') |
命令式用法一致 |
主要差异:
- ay-popup 额外支持
v-model:show声明式用法 open()/close()返回 Promise- 新增
round、closeable、before-close、swipe-close等属性 - 新增
opened、closed动画完成事件
许可
MIT License

收藏人数:
下载插件并导入HBuilderX
下载示例项目ZIP
赞赏(0)
下载 171
赞赏 1
下载 11291367
赞赏 1862
赞赏
京公网安备:11010802035340号