云龙叔叔
云龙叔叔
  • 发布:2020-08-10 10:34
  • 更新:2023-07-06 16:41
  • 阅读:47366

uni.showModal 弹窗自定义内容样式解决方案

分类:uni-app

前言

因为各种版本的手机上Modal 原生弹窗各不相同且无法修改内容及样式,所以需要一个高度自定义的弹窗以解决弹窗样式各端不同的问题

app解决思路

使用app-plus "background": "transparent" 可以实现伪弹窗(其实是打开一个背景透明的页面),缺点返回时会触发onShow需要进行处理,

app代码

//pages.json  
        {  
            "path": "components/modal/confirmModal/index",  
            "style": {  
                "navigationStyle": "custom",  

                "app-plus": {  
                    "animationType": "fade-in",  
                    "background": "transparent",  
                    "backgroundColor": "rgba(0,0,0,0)",  
                    "popGesture": "none"  
                }  
            }  
        }  
//main.js  
import showModal from '@/common/js/modal.js'  
Vue.prototype.$showModal = showModal  

//modal.js  
let $showModal = function(option) {  
            let params = {  
            title: "",  
            content: "",   
            cancelText: "取消", // 取消按钮的文字  
            confirmText: "确定", // 确认按钮文字  
            showCancel: true, // 是否显示取消按钮,默认为 true  

        }  

        Object.assign(params, option)  
        // #ifdef APP-PLUS  
        let list = []  
        Object.keys(params).forEach(ele => {  
            list.push(ele + "=" + params[ele])  
        })  
        let paramsStr = list.join('&')  

                uni.navigateTo({  
            url: `/components/modal/confirmModal/index?${paramsStr}`  
        });  

        return new Promise((resolve, reject) => {  
            uni.$once("AppModalCancel", () => {  
                reject()  
            })  
            uni.$once("AppModalConfirm", (e) => {  
                resolve(e)  
            })  
        });  
        // #endif  

        // #ifndef APP-PLUS  
        return new Promise((resolve,reject)=>{  
            uni.showModal({  
                title:params.title,  
                content: params.content,   
                cancelText:  params.cancelText,   
                confirmText:  params.confirmText,   
                showCancel: params.showCancel,   
                success: (res) => {  
                    if(res.confirm) {  
                        resolve()  
                    } else {  
                        reject()  
                    }  
                }  
            });  
        })  
        // #endif  

}  

export default $showModal  

//页面调用方法  
  this.$showModal({  
    title: '确定删除吗',  
    content: '',  
    cancelText:'取消',  
    confirmText: '确认'  
}).then(res =>{}).catch(err=>{})  

confirmModal 必须使用nvue页面,不然页面是不透明的

<template>  
    <view class="app-modal">  
        <view class="app-modal__container">  
            <view class="app-modal__container__header" v-if="title">  
                <text class="app-modal__container__header__text">{{title}}</text>  
            </view>  
            <view class="app-modal__container__content">  
                <view v-if="input"  class="content_input">  
                    <input v-model="inputContent" class="input" placeholder-class="input" :placeholder="inputContent" maxlength="20" type="text"></input>  
                </view>  
                <text class="app-modal__container__content__text" :style="{textAlign: align}">{{content}}</text>  

            </view>  
            <view class="app-modal__container__footer">  
                <view v-if="showCancel" style="width: 226rpx" class="app-modal__container__footer-left" hover-class="app-modal__container__footer-hover" :hover-start-time="20" :hover-stay-time="70" @click="clickLeft" >  
                    <text class="app-modal__container__footer-left__text">{{cancelText}}</text>  
                </view>  
                <view :style="{width: showCancel?'226rpx':'452rpx'}" class="app-modal__container__footer-right" hover-class="app-modal__container__footer-hover" :hover-start-time="20" :hover-stay-time="70" @click="clickRight"  >  
                    <text class="app-modal__container__footer-right__text" >{{confirmText}}</text>  
                </view>  
            </view>  
        </view>  
    </view>  
</template>  

<script>  
    export default {  
        data() {  
            return {  
                title: "",  
                content: "",   
                input:false,  
                inputContent:'',  
                align: "center", // 对齐方式 left/center/right  
                cancelText: "取消", // 取消按钮的文字  
                confirmText: "确定", // 确认按钮颜色  
                showCancel: true, // 是否显示取消按钮,默认为 true  
            };  
        },  
        onBackPress(options) {  
            if (options.from === 'navigateBack') {  
                return false;    
            }    
            return true;    
        },  
        onLoad(options) {  
            if (options.showCancel) {  
                options.showCancel = JSON.parse(options.showCancel)  
            }  
            Object.assign(this.$data, options)  
        },  
        methods: {  
            clickLeft() {  
                // 先关闭后发送事件  
                this.closeModal();  
                uni.$emit('AppModalCancel')  
            },  
            clickRight() {  
                // 先关闭后发送事件  
                this.closeModal();  
                uni.$emit('AppModalConfirm',this.inputContent)  
            },  
            closeModal() {  
                uni.navigateBack();  
            }  
        }  
    }  
</script>  

<style lang="scss">  
    // nvue页面只支持flex布局  
    //样式自定义  
</style>  

H5弹窗解决思路

全局修改uni.showModal 弹窗样式

H5代码

/* #ifndef APP-PLUS */  
//自己打开个H5modal  选择元素 改成自己需要的modal 样式  
uni-modal {  
     .uni-modal {}  
}  
/* #endif */
4 关注 分享
maozai 不瞌睡 邢牧 1***@qq.com

要回复文章请先登录注册

小金家的沐沐

小金家的沐沐

其实不同的平台是遵从不同的平台的设计原则的。IOS自己设计了一套他自己平台的弹窗,Google也给Android设计了一套。所以感觉想要完全追求一直就奇怪呢。
2023-07-06 16:41
1***@qq.com

1***@qq.com

试过了,不生效的
2023-03-21 09:41
312860

312860

页面嵌套超过3层调用这个弹窗就是4层 取消返回就会闪退 怎么处理
2022-03-10 11:01
达摩克利斯之剑

达摩克利斯之剑

自定义弹框会有穿透的问题
2021-09-16 17:47