更新记录
1.0.0(2026-10-28)
下载此版本
平台兼容性
uni-app(3.8.10)
| Vue2 |
Vue3 |
Chrome |
Safari |
app-vue |
app-nvue |
Android |
iOS |
鸿蒙 |
| √ |
√ |
√ |
√ |
√ |
- |
√ |
√ |
- |
| 微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
小红书小程序 |
快应用-华为 |
快应用-联盟 |
| √ |
√ |
√ |
√ |
√ |
√ |
- |
√ |
√ |
√ |
- |
- |
其他
| 多语言 |
暗黑模式 |
宽屏模式 |
蒸汽模式 |
| × |
× |
√ |
× |
o-modal
通用弹层组件 o-modal
- 路径符合 uni_modules 插件规范,页面无需 import/注册,直接写 即可
- 支持 v-model(Vue2)和 v-model:visible(Vue3),双端兼容
- 关键设计:每个弹层传一个 name 标识,确认/取消/点遮罩统一通过 @action 事件抛出 { name, action },这是多弹层共用一个回调的基础
- 内置:遮罩、居中缩放进出场动画、内容超长滚动(max-height 60vh)、title/默认内容插槽、showCancel、maskClosable、zIndex 等配置,touchmove 已阻止穿透
- 页面里多个弹层,只维护一个状态 + 共用方法,不再写一堆 visible1、showXxx 布尔值
代码示例
<template>
<view class="page">
<view class="page-title">o-modal 多弹层共用一个方法示例</view>
<view class="btn" hover-class="btn--hover" @click="openModal('delete')">删除确认弹窗</view>
<view class="btn" hover-class="btn--hover" @click="openModal('logout')">退出登录弹窗</view>
<view class="btn" hover-class="btn--hover" @click="openModal('custom')">自定义内容弹窗</view>
<view class="btn" hover-class="btn--hover" @click="openModal('notice')">纯内容弹窗(无底部按钮)</view>
<view class="btn" hover-class="btn--hover" @click="openModal('subscribe')">自定义底栏弹窗</view>
<view class="section-title">定位示例(position)</view>
<view class="pos-grid">
<view class="pos-btn" hover-class="btn--hover" @click="openModal('posTop')">上 top</view>
<view class="pos-btn" hover-class="btn--hover" @click="openModal('posBottom')">下 bottom</view>
<view class="pos-btn" hover-class="btn--hover" @click="openModal('posLeft')">左 left</view>
<view class="pos-btn" hover-class="btn--hover" @click="openModal('posRight')">右 right</view>
</view>
<!-- 弹层1:删除确认(只要确定) -->
<o-modal
:visible="currentModal === 'delete'"
name="delete"
title="删除确认"
content="删除后不可恢复,确定删除该条数据吗?"
:show-cancel="false"
confirm-text="删除"
@action="onModalAction"
/>
<!-- 弹层2:退出登录 -->
<o-modal
:visible="currentModal === 'logout'"
name="logout"
title="提示"
content="确定要退出当前账号吗?"
@action="onModalAction"
/>
<!-- 弹层3:自定义插槽内容 -->
<o-modal :visible="currentModal === 'custom'" name="custom" title="协议确认" @action="onModalAction">
<view class="custom-body">
<text class="custom-text">请阅读并同意以下协议:</text>
<text class="custom-link">《用户服务协议》</text>
<text class="custom-link">《隐私政策》</text>
</view>
</o-modal>
<!-- 弹层4:只要内容,不要底部按钮(点遮罩关闭) -->
<o-modal
:visible="currentModal === 'notice'"
name="notice"
title="系统通知"
content="系统将于今晚 23:00 - 24:00 维护升级,期间部分功能不可用,请提前保存数据。"
:show-cancel="false"
:show-confirm="false"
@action="onModalAction"
/>
<!-- 弹层5:底部区域完全自定义(footer 插槽) -->
<o-modal :visible="currentModal === 'subscribe'" name="subscribe" title="订阅提醒">
<view class="custom-body">
<text class="custom-text">开启后,活动开始前 1 小时会通知你。</text>
</view>
<template #footer>
<view class="custom-footer">
<view class="custom-footer__btn" hover-class="btn--hover" @click="onFooterAction('later')">以后再说</view>
<view class="custom-footer__btn custom-footer__btn--primary" hover-class="btn--hover" @click="onFooterAction('now')">
立即开启
</view>
</view>
</template>
</o-modal>
<!-- 定位示例:上 -->
<o-modal
:visible="currentModal === 'posTop'"
name="posTop"
position="top"
title="顶部弹出"
content="从顶部滑入,常用于通知条、筛选条。"
:show-cancel="false"
@action="onModalAction"
/>
<!-- 定位示例:下(底部面板,自动适配安全区) -->
<o-modal
:visible="currentModal === 'posBottom'"
name="posBottom"
position="bottom"
title="底部弹出"
content="从底部滑入的全宽面板,常用于操作面板、筛选面板。"
@action="onModalAction"
/>
<!-- 定位示例:左(抽屉) -->
<o-modal
:visible="currentModal === 'posLeft'"
name="posLeft"
position="left"
title="左侧抽屉"
content="从左侧滑入的抽屉面板。"
@action="onModalAction"
/>
<!-- 定位示例:右(抽屉) -->
<o-modal
:visible="currentModal === 'posRight'"
name="posRight"
position="right"
title="右侧抽屉"
content="从右侧滑入的抽屉面板,常用于筛选、设置面板。"
@action="onModalAction"
/>
<!-- 示例:只要一个确认按钮 -->
<!-- <o-modal :visible="currentModal === 'onlyConfirm'" name="onlyConfirm" title="提示"
content="操作已提交" :show-cancel="false" @action="onModalAction" /> -->
</view>
</template>
<script>
export default {
data() {
return {
// 当前打开的弹层标识:整页只有一个状态,不再需要 visible1/visible2/showXxx 一堆布尔值
currentModal: ''
}
},
methods: {
// 【共用方法一】打开:任何弹层都调这一个
openModal(name) {
this.currentModal = name
},
// 【共用方法二】关闭:任何弹层都调这一个
closeModal() {
this.currentModal = ''
},
// 【共用方法三】所有弹层的确认/取消统一回调,通过 name 区分来源
onModalAction({ name, action }) {
if (action === 'confirm') {
switch (name) {
case 'delete':
uni.showToast({ title: '已删除', icon: 'success' })
break
case 'logout':
uni.showToast({ title: '已退出登录', icon: 'success' })
break
case 'custom':
uni.showToast({ title: '已同意协议', icon: 'success' })
break
}
}
// 无论 confirm / cancel / mask,统一关闭
this.closeModal()
},
// 自定义底栏的按钮回调(插槽内容由页面自己控制)
onFooterAction(type) {
this.closeModal()
if (type === 'now') {
uni.showToast({ title: '已开启提醒', icon: 'success' })
}
}
}
}
</script>