uni-app 封装底部滑动弹出模态框组件

作者:百宝袋

时间:2026-10-31

浏览:422

本文介绍如何在 uni-app 中封装一个底部滑出的模态框组件。通过定义 BottomModal 子组件,利用 CSS 控制显示状态与高度变化,实现平滑的滑动动画效果。父组件通过 props 传入 showModal 状态控制组件显隐,并可在模态框内自定义内容区域,适用于订单确认、选项选择等场景。

文章目录

子组件 BottomModal 实现

首先定义子组件 BottomModal,该组件接收一个布尔类型的 props 参数 showModal,默认值为 false,用于控制模态框的显示与隐藏。模板部分包含一个外层容器 bottom-modal,应用 show 类名以触发 CSS 动画;内部为 modal-content 区域,通过 slot 插槽允许父组件传入自定义内容。样式方面,利用 transition 属性设置高度变化的过渡时间为 0.5 秒,线性渐变。当 showModal 为 true 时,modal-content 添加 show 类,高度变为 60vh。同时定义 modal-mask 为绝对定位遮罩层,覆盖整个屏幕区域。

<template>
    <div class="bottom-modal" :class="{'show': showModal}">
      <div class="modal-content" :class="{'show': showModal}">
        <!-- 内容区域 -->
        <slot></slot>
      </div>
    </div>
  </template>
  <script>
  export default {
    name: 'BottomModal',
    props: {
      showModal: {
        type: Boolean,
        default: false
      }
    },
    methods: {
    }
  }
  </script>
  <style lang="scss">
  .bottom-modal {
    position: fixed;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 0;
    background-color: rgba(0, 0, 0, 0.5);
    overflow: hidden;
    transition: height 0.2s ease-out;
    z-index: 99;
  }
  .bottom-modal.show {
    height: 100%;
  }
  .modal-content {
    background-color: #fff;
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
    box-shadow: 0px -2px 10px rgba(0, 0, 0, 0.1);
    padding: 16px;
    // 内容显示在底部
    position: absolute;
    left: 0;
    bottom: 0;
    box-sizing: border-box;
    width: 100%;
    z-index: 999;
    height: 0;
    transition: all 0.5s linear;
  }
  .modal-content.show {
    height: 60vh;
  }
  .modal-mask {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }
  </style>

父组件调用与状态控制

在父组件中引入封装好的 BottomModal 组件,并在 data 中定义 showModal 变量初始为 false。通过 :showModal="showModal" 将状态传递给子组件。在 methods 中可定义如 radioChange 等方法处理内部交互事件。模板中使用 <bottom-modal> 标签包裹自定义内容,例如包含标题、单选按钮及确认按钮的订单取消界面。通过绑定 showModal 状态控制模态框的弹出与收起,实现用户交互逻辑。

<script>
import BottomModal from "@/components/BottomModal.vue"
export default {
    components: {
        BottomModal
    },
    data() {
		return {
		    showModal: false
		}
	},
	methods: {
        radioChange(e) {
            console.log("radioChange", e.detail.value)
        }
	}
}
</script>
<template>
    <bottom-modal :showModal="showModal">
        <view class="my-modal">
            <text class="title">订单取消</text>
            <text>请选择取消订单的原因:</text>
            <radio-group @change="radioChange">
                <view>
                    <label class="item">
                        <text>商品无货</text>
                        <radio :value="1" style="transform: scale(0.6)" />
                    </label>
                </view>
                <view>
                    <label class="item">
                        <text>不想要了</text>
                        <radio :value="2" style="transform: scale(0.6)" />
                    </label>
                </view>
                <view>
                    <label class="item">
                        <text>商品信息填错了</text>
                        <radio :value="3" style="transform: scale(0.6)" />
                    </label>
                </view>
                <view>
                    <label class="item">
                        <text>地址信息填写错误</text>
                        <radio :value="4" style="transform: scale(0.6)" />
                    </label>
                </view>
                <view>
                    <label class="item">
                        <text>商品降价</text>
                        <radio :value="5" style="transform: scale(0.6)" />
                    </label>
                </view>
                <view>
                    <label class="item">
                        <text>其它</text>
                        <radio :value="6" style="transform: scale(0.6)" />
                    </label>
                </view>
            </radio-group>
            <view class="cancel-confirm">
                <text @click="handleCancel">取消</text>
                <text @click="handleConfirm" class="confirm">确认</text>
            </view>
        </view>
    </bottom-modal>
</template>
<style lang="scss">
.my-modal {
    display: flex;
    flex-direction: column;
    font-size: 26rpx;
    .item {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-top: 30rpx;
        padding-right: 30rpx;
    }
    .title {
        margin-top: 15rpx;
        font-size: 30rpx;
        text-align: center;
    }
    .cancel-confirm {
        display: flex;
        justify-content: space-around;
        margin-top: 30rpx;
        text {
            width: 300rpx;
            height: 60rpx;
            line-height: 60rpx;
            text-align: center;
            border: 1px solid #e6e2e2;
            border-radius: 30rpx;
        }
        .confirm {
            background-color: #27BA9B;
            border: none;
            color: #fff;
        }
    }
}
</style>

模态框效果展示

展示模态框弹出后的实际视觉效果,包括遮罩层覆盖、内容区域从底部滑出并固定高度为 60vh 的动画过程,以及确认按钮等交互元素的布局表现。

子组件 BottomModal 实现

总结

至此,关于在 uni-app 中封装实现底部滑动弹出模态框组件的介绍已完成。如需了解更多相关技术细节,可查阅本站往期文章或继续浏览后续内容。感谢支持,欢迎持续关注我们获取更多前端开发技巧。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章