vue模态框组件封装

本文详细介绍了uni-app中模态框组件的使用方法,包括不同样式的按钮配置、遮罩层交互、自定义内容及多种触发事件的处理。通过实例展示了如何创建一般弹框、提示文本、单个或多个按钮的模态框,以及如何设置按钮颜色和圆角样式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码已上传至github
github代码地址:https://github.com/Miofly/mio.git

 示例代码

<template>
    <view class="container padding bg-white">
        <!--<text>{{dateUtils.beforeWeekFirst}}</text>-->
        <view class="flex flex-direction">
            <button class="round cu-btn line-blue margin-top" @click='show'>一般弹框</button>
            <button class="round cu-btn line-blue margin-top" @click='show2'>提示文本样式</button>
            <button class="round cu-btn line-blue margin-top" @click='show3'>单个按钮</button>
            <button class="round cu-btn line-blue margin-top" @click="show4">多个按钮</button>
            <button class="round cu-btn line-blue margin-top" @click="show5">圆角按钮</button>
            <button class="round cu-btn line-blue margin-top" @click="show6">按钮颜色</button>
            <button class="round cu-btn line-blue margin-top" @click="show7">遮罩不可点</button>
            <button class="round cu-btn line-blue margin-top" @click="show8">自定义弹窗内容</button>
        </view>

        <modal :show="modal" @click="handleClick" @cancel="hide" title="提示" content="确定退出登录吗?"></modal>

        <modal :show="modal2" @click="handleClick2" @cancel="hide2" content="确定退出登录吗?" color="blue" :size="32"></modal>

        <modal :show="modal3" @click="handleClick3" @cancel="hide3" content="您还未登录,请先登录" :button="button3"></modal>

        <modal :show="modal4" @click="handleClick4" @cancel="hide4" content="请选择支付方式" :button="button4"></modal>

        <modal :show="modal5" @click="handleClick5" @cancel="hide5" content="确定退出登录吗?" color="#333" :size="32" shape="circle"></modal>

        <modal :show="modal6" @click="handleClick6" @cancel="hide6" content="确定退出登录吗?" color="#333" :size="32" :button="button6"></modal>

        <modal :show="modal7" @click="handleClick7" @cancel="hide7" content="您还未登录,请先登录" :button="button3" :maskClosable="false"></modal>

        <modal :show="modal8" @cancel="hide8" :custom="true">
            <view class="mio-modal-custom">
                <image src="http://img2.imgtn.bdimg.com/it/u=1344996754,553300684&fm=26&gp=0.jpg" class="mio-tips-img"></image>
                <view class="mio-modal-custom-text">我是自定内容</view>
                <button class="cu-btn bg-blue block round">常用大按钮</button>
            </view>
        </modal>

		<!--test (e) {if (e.index == 0) {console.log('点击了第一个按钮')}if (e.index == 1) {console.log('点击了第二个按钮')}}-->
		<modal title="标题111" content="这是内容" @click="test" color="#999" :size="32" :maskClosable="false"
				:show="status" @cancel="status = false" shape="['circle', 'square'][1]"
				:button="[{text: '微信', type: ['green', 'default', 'primary', 'red', 'danger', 'warning', 'white', 'gray'][5], plain: true},
				{text: '支付宝', plain: false}]" :custom="true">
			<view class="fa fa-close" style="position: absolute; top:20px;right: 20px" @tap="status = false"></view>
		</modal>
    </view>
</template>

<script>
    import {ui} from 'mioJs/uniapp'

    export default {
        data () {
            return {
                status: true,
                modal: false,
                modal2: false,
                modal3: false,
                button3: [{
                    text: '确定',
                    type: 'red'
                }],
                modal4: false,
                button4: [{
                    text: '微信',
                    type: 'green',
                    plain: true
                }, {
                    text: '支付宝',
                    plain: true
                }, {
                    text: '银行卡',
                    type: 'red',
                    plain: true
                }],
                modal5: false,
                modal6: false,
                button6: [{
                    text: '取消',
                    type: 'gray'
                }, {
                    text: '确定'
                }],
                modal7: false,
                modal8: false,
                modal9: false,
                email: ''
            }
        },
        methods: {
            show () {
                this.modal = true
            },
            show2 () {
                this.modal2 = true
            },
            show3 () {
                this.modal3 = true
            },
            show4 () {
                this.modal4 = true
            },
            show5 () {
                this.modal5 = true
            },
            show6 () {
                this.modal6 = true
            },
            show7 () {
                this.modal7 = true
            },
            show8 () {
                this.modal8 = true
            },
            hide () {
                this.modal = false
            },
            hide2 () {
                this.modal2 = false
            },
            hide3 () {
                this.modal3 = false
            },
            hide4 () {
                this.modal4 = false
            },
            hide5 () {
                this.modal5 = false
            },
            hide6 () {
                this.modal6 = false
            },
            hide7 () {
                this.modal7 = false
            },
            hide8 () {
                this.modal8 = false
            },
            handleClick (e) {
                const index = e.index
                if (index === 0) {
                    ui.showToast('你点击了取消按钮')
                } else {
                    ui.showToast('你点击了确定按钮', 'success')
                    this.ui.showToast('复制成功')
                }
                // this.hide()
            },
            handleClick2 (e) {
                const index = e.index
                if (index === 0) {
                    ui.showToast('你点击了取消按钮')
                } else {
                    ui.showToast('')
                }
                this.hide2()
            },
            handleClick3 (e) {
                const index = e.index
                if (index === 0) {
                    ui.showToast('你点击了确定按钮')
                }
                this.hide3()
            },
            handleClick4 (e) {
                const index = e.index
                ui.showToast('你点击的按钮index:' + index)
                this.hide4()
            },
            handleClick5 (e) {
                const index = e.index
                ui.showToast('你点击的按钮index:' + index)
                this.hide5()
            },
            handleClick6 (e) {
                const index = e.index
                ui.showToast('你点击的按钮index:' + index)
                this.hide6()
            },
            handleClick7 (e) {
                const index = e.index
                ui.showToast('你点击的按钮index:' + index)
                this.hide7()
            },
            handleClick8 () {
                ui.showToast('你点击了自定义按钮')
                this.hide8()
            },
        }
    }
</script>

组件代码

<template>
    <view @touchmove.stop.prevent>
        <view class="mio-modal-box" :style="{width:width,padding:padding,borderRadius:radius}"
			  :class="[(fadein || show)?'mio-modal-normal':'mio-modal-scale',show?'mio-modal-show':'']">
            <view v-if="!custom">
                <view v-if="closeShow" class="fa fa-close"
                      style="position: absolute; top:20px;right: 20px"
                      @tap="closeCancel"></view>
                <view class="mio-modal-title" v-if="title">{{title}}</view>
                <view class="mio-modal-content" :class="[title?'':'mio-mtop']" :style="{color:color,fontSize:size+'rpx'}">{{content}}</view>
                <view class="mio-modalBtn-box" :class="[button.length!=2?'mio-flex-column':'']">
                    <block v-for="(item,index) in button" :key="index">
                        <button class="mio-modal-btn" :class="['mio-'+(item.type || 'primary')+(item.plain?'-outline':''),
                        button.length!=2?'mio-btn-width':'',button.length>2?'mio-mbtm':'',
                        shape=='circle'?'mio-circle-btn':'']"
                        :hover-class="'mio-'+(item.plain?'outline':(item.type || 'primary'))+'-hover'" :data-index="index" @tap="handleClick">{{item.text || "确定"}}</button>
                    </block>
                </view>
            </view>
            <view v-else>
                <slot></slot>
            </view>
        </view>
        <view class="mio-modal-mask" :class="[show?'mio-mask-show':'']" @tap="handleClickCancel"></view>
    </view>
</template>

<script>
    export default {
        props: {
            // 是否显示
            show: {
                type: Boolean,
                default: false
            },
            // 是否显示
            closeShow: {
                type: Boolean,
                default: true
            },
            width: {
                type: String,
                default: '84%'
            },
            padding: {
                type: String,
                default: '40rpx 64rpx'
            },
            radius: {
                type: String,
                default: '24rpx'
            },
            // 标题
            title: {
                type: String,
                default: ''
            },
            // 内容
            content: {
                type: String,
                default: ''
            },
            // 内容字体颜色
            color: {
                type: String,
                default: '#999'
            },
            // 内容字体大小 rpx
            size: {
                type: Number,
                default: 28
            },
            // 形状 circle, square
            shape: {
                type: String,
                default: 'square'
            },
            button: {
                type: Array,
                default: function () { // red
                    return [{
                        text: '取消',
                        type: 'default',
                        plain: true // 是否空心
                    }, {
                        text: '确定',
                        type: 'primary',
                        plain: false
                    }]
                }
            },
            // 点击遮罩 是否可关闭
            maskClosable: {
                type: Boolean,
                default: true
            },
            // 自定义弹窗内容
            custom: {
                type: Boolean,
                default: false
            },
            // 淡入效果,自定义弹框插入input输入框时传true
            fadein: {
                type: Boolean,
                default: false
            }
        },
        data () {
            return {

            }
        },
        methods: {
            closeCancel () {
                if (!this.maskClosable) return
                this.$emit('cancel')
            },
            handleClick (e) {
                if (!this.show) return
                const dataset = e.currentTarget.dataset
                this.$emit('click', {
                    index: Number(dataset.index)
                })
            },
            handleClickCancel () {
                if (!this.maskClosable) return
                this.$emit('cancel')
            }
        }
    }
</script>

<style>
	.mio-modal-box {
		position: fixed;
		left: 50%;
		top: 50%;
		margin: auto;
		background: #fff;
		z-index: 999;
		transition: all 0.3s ease-in-out;
		opacity: 0;
		box-sizing: border-box;
		visibility: hidden;
	}

	.mio-modal-scale {
		transform: translate(-50%, -50%) scale(0);
	}

	.mio-modal-normal {
		transform: translate(-50%, -50%) scale(1);
	}

	.mio-modal-show {
		opacity: 1;
		visibility: visible;
	}

	.mio-modal-mask {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		background: rgba(0, 0, 0, 0.6);
		z-index: 888;
		transition: all 0.3s ease-in-out;
		opacity: 0;
		visibility: hidden;
	}

	.mio-mask-show {
		visibility: visible;
		opacity: 1;
	}

	.mio-modal-title {
		text-align: center;
		font-size: 34rpx;
		color: #333;
		padding-top: 20rpx;
		font-weight: bold;
	}

	.mio-modal-content {
		text-align: center;
		color: #999;
		font-size: 28rpx;
		padding-top: 20rpx;
		padding-bottom: 60rpx;
	}

	.mio-mtop {
		margin-top: 30rpx;
	}

	.mio-mbtm {
		margin-bottom: 30rpx;
	}

	.mio-modalBtn-box {
		width: 100%;
		display: flex;
		align-items: center;
		justify-content: space-between
	}

	.mio-flex-column {
		flex-direction: column;
	}

	.mio-modal-btn {
		width: 46%;
		height: 68rpx;
		line-height: 68rpx;
		position: relative;
		border-radius: 10rpx;
		font-size: 24rpx;
		overflow: visible;
		margin-left: 0;
		margin-right: 0;
	}

	.mio-modal-btn::after {
		content: "";
		position: absolute;
		width: 200%;
		height: 200%;
		-webkit-transform-origin: 0 0;
		transform-origin: 0 0;
		-webkit-transform: scale(0.5, 0.5);
		transform: scale(0.5, 0.5);
		left: 0;
		top: 0;
		border-radius: 20rpx;
	}

	.mio-btn-width {
		width: 80% !important;
	}

	.mio-primary {
		background: #5677fc;
		color: #fff;
	}

	.mio-primary-hover {
		background: #4a67d6;
		color: #e5e5e5;
	}

	.mio-primary-outline {
		color: #5677fc;
		background: none;
	}

	.mio-primary-outline::after {
		border: 1px solid #5677fc;
	}

	.mio-danger {
		background: #ed3f14;
		color: #fff;
	}

	.mio-danger-hover {
		background: #d53912;
		color: #e5e5e5;
	}

	.mio-danger-outline {
		color: #ed3f14;
		background: none;
	}

	.mio-danger-outline::after {
		border: 1px solid #ed3f14;
	}

	.mio-red {
		background: #e41f19;
		color: #fff;
	}

	.mio-red-hover {
		background: #c51a15;
		color: #e5e5e5;
	}

	.mio-red-outline {
		color: #e41f19;
		background: none;
	}

	.mio-red-outline::after {
		border: 1px solid #e41f19;
	}

	.mio-warning {
		background: #ff7900;
		color: #fff;
	}

	.mio-warning-hover {
		background: #e56d00;
		color: #e5e5e5;
	}

	.mio-warning-outline {
		color: #ff7900;
		background: none;
	}

	.mio-warning-outline::after {
		border: 1px solid #ff7900;
	}

	.mio-green {
		background: #19be6b;
		color: #fff;
	}

	.mio-green-hover {
		background: #16ab60;
		color: #e5e5e5;
	}

	.mio-green-outline {
		color: #19be6b;
		background: none;
	}

	.mio-green-outline::after {
		border: 1px solid #19be6b;
	}

	.mio-white {
		background: #fff;
		color: #333;
	}

	.mio-white-hover {
		background: #f7f7f9;
		color: #666;
	}

	.mio-white-outline {
		color: #333;
		background: none;
	}

	.mio-white-outline::after {
		border: 1px solid #333;
	}

	.mio-gray {
		background: #ededed;
		color: #999;
	}

	.mio-gray-hover {
		background: #d5d5d5;
		color: #898989;
	}

	.mio-gray-outline {
		color: #999;
		background: none;
	}

	.mio-gray-outline::after {
		border: 1px solid #999;
	}

	.mio-outline-hover {
		opacity: 0.6;
	}

	.mio-circle-btn {
		border-radius: 40rpx !important;
	}

	.mio-circle-btn::after {
		border-radius: 80rpx !important;
	}
</style>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wflynn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值