(uniapp)小程序实现自定义弹框,自定义样式showmodal

发布时间 2023-11-20 11:58:55作者: 木狼

在components里新建自定义弹框组件——modal.vue

<template>
    <!-- 自定义弹窗 -->
    <view class="_showModal" v-show="show">
        <view class="_shade"></view>
        <view class="_modalBox">
            <view class="_modal">
                <image src="../static/upgrade.png" mode="widthFix" class="bg-upgrade"></image>
                <slot name="title">
                    <view class="title">{{'发现新版本'+title+',是否重启应用'}}</view>
                </slot>
                <view class="content">本次版本更新内容</view>
                <view v-for="(item,index) in content" :key="index">
                    <slot name="content">
                        <view class="content">{{(index+1)+'、'+item}}</view>
                    </slot>
                </view>
                <slot name="btn">
                    <view class="btnbox">
                        <!-- <view v-if="cancelText" class="btn"
                            :style="{color:cancelColor,background:cancelBackgroundColor}"
                            @click.stop="clickBtn('cancel')">{{cancelText}}</view> -->
                        <view class="btn" :style="{color:confirmColor,background:confirmBackgroundColor}"
                            @click.stop="clickBtn('confirm')">{{confirmText}}</view>
                    </view>
                </slot>
            </view>
        </view>
    </view>
</template>

<script>
    export default {
        name: "show-modal",
        computed: {
            show() {
                return this.$modalStore.state.mshow;
            },
            title() {
                return this.$modalStore.state.mtitle;
            },
            content() {
                return this.$modalStore.state.mcontent;
            },
            showCancel() {
                return this.$modalStore.state.mshowCancel;
            },
            cancelText() {
                return this.$modalStore.state.mcancelText;
            },
            cancelColor() {
                return this.$modalStore.state.mcancelColor;
            },
            cancelBackgroundColor() {
                return this.$modalStore.state.mcancelBackgroundColor;
            },
            confirmText() {
                return this.$modalStore.state.mconfirmText;
            },
            confirmColor() {
                return this.$modalStore.state.mconfirmColor;
            },
            confirmBackgroundColor() {
                return this.$modalStore.state.mconfirmBackgroundColor;
            }
        },
        methods: {
            closeModal() {
                this.$modalStore.commit('hideModal')
            },
            clickBtn(res) {
                this.$modalStore.commit('hideModal')
                this.$modalStore.commit('success', res)
            }
        },
        beforeDestroy() {
            this.$modalStore.commit('hideModal')
        },
        data() {
            return {

            };
        }
    }
</script>

<style lang="scss" scoped>
    ._showModal {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 10000;

        ._shade {
            width: 100%;
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
            background: #000;
            opacity: .6;
            z-index: 11000;
        }

        ._modalBox {
            width: 100%;
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 12000;
            display: flex;
            justify-content: center;
            align-items: center;

            ._modal {
                flex: none;
                width: 345px;
                height: auto;
                background: #fff;
                border-radius: 12px;
                position: relative;
                padding: 60rpx 0 30rpx 0;

                .bg-upgrade {
                    position: absolute;
                    top: -100rpx;
                    left: 0;
                    right: 0;
                    margin: auto;
                    width: 60%;
                }

                .title {
                    text-align: center;
                    font-size: 18px;
                    font-family: Source Han Sans CN;
                    font-weight: bold;
                    color: #333333;
                    margin: 70px 0 20px 0;
                }

                .content {
                    width: 80%;
                    margin: 20rpx auto;
                    font-size: 14px;
                    font-family: Source Han Sans CN;
                    color: #898989;
                    display: flex;
                    // justify-content: center;
                    align-items: center;
                    word-break: break-all;
                }

                .btnbox {
                    display: flex;
                    justify-content: center;
                    // padding-top: 10px;
                    flex-direction: row;

                    .btn {
                        width: 100%;
                        height: 80rpx;
                        border-radius: 80rpx;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        font-family: Source Han Sans CN;
                        font-weight: 500;
                        font-size: 16px;
                        margin: 30rpx 30rpx 20rpx 30rpx;
                    }
                }
            }
        }

    }
</style>

在utils里新建modal.js

import Vuex from 'vuex'
// 自定义弹窗
export default function initModal(v) {
    // 挂在store到全局Vue原型上
    v.prototype.$modalStore = new Vuex.Store({
        state: {
            mshow: false,
            mtitle: "",
            mcontent: [],
            mshowCancel: true,
            mcancelText: "取消",
            mcancelColor: "#333333",
            mcancelBackgroundColor: "rgba(236, 236, 236, 0.39)",
            mconfirmText: "确定",
            mconfirmColor: "#333333",
            mconfirmBackgroundColor: "#FFBB24",
            msuccess: null,
        },
        mutations: {
            hideModal(state) {
                // 小程序导航条页面控制
                // #ifndef H5
                if (state.mhideTabBar) {
                    wx.showTabBar();
                }
                // #endif
                state.mshow = false
            },
            showModal(state, data) {
                state = Object.assign(state, data)
                console.log(state);
                state.mshow = true
            },
            success(state, res) {
                let cb = state.msuccess
                let resObj = {
                    cancel: false,
                    confirm: false
                }
                res == "confirm" ? resObj.confirm = true : resObj.cancel = true
                cb && cb(resObj)
            }
        }
    })
    v.prototype.$showModal = function(option) {
        if (typeof option === 'object') {
            // #ifndef H5
            if (option.hideTabBar) {
                wx.hideTabBar();
            }
            // #endif

            v.prototype.$modalStore.commit('showModal', option)
        } else {
            throw "配置项必须为对象传入的值为:" + typeof option;
        }
    }
}

在项目根目录vue.config.js(没有就新建)文件插入下面代码

module.exports = {
    chainWebpack: config => {
        config.module.rule('vue').use('vue-loader').loader('vue-loader').tap(options => {
            const compile = options.compiler.compile
            options.compiler.compile = (template, ...args) => {
                if (args[0].resourcePath.match(/^pages/)) {
                    template = template.replace(/[\s\S]+?<[\d\D]+?>/, _ => `${_}
                    <updagrade ref="updagrade" />`)
                }
                return compile(template, ...args)
            }
            return options
        })
    }
}

在main.js文件里全局引入

import modaljs from './utils/modal.js'
import modalvue from '@/components/modal.vue'
modaljs(Vue)
Vue.component('modal',modalvue)