更新记录

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>

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

许可协议

MIT协议

暂无用户评论。