...
大前端

uniapp全局弹窗APP做全局弹窗(dialog)插件的思路

由于uniapp做的app没办法操作dom,install的dom操作都无法实现全局dialog

网上有三种方法

  1. 可以使用subnvue webview子窗体
  2. 使用 plus.nativeObj.View
  3. 新建一个页面进行跳转,可以实现伪弹窗(其实是打开一个背景透明的页面)
    前两种工有点大,就选第三种吧。

先写一个dialog的vue页面方在components目录下

dialog.vue

<template>
    <view>
        <view class="diaglog-mask"></view>
        <view class="diaglog">
            <view class="diaglog-title">
                {{param.title}}
            </view>
            <view class="diaglog-content">
                <rich-text :nodes="param.content"></rich-text>
            </view>
            <view class="diaglog-btns">
                <view class="diaglog-btns-button" :style="{color:param.cancelColor}" @click="cancelClick">
                    {{param.cancelText}}
                </view>
                <view class="diaglog-btns-button" :style="{color:param.confirmColor}" @click="confirmClick">
                    {{param.confirmText}}
                </view>
            </view>
        </view>
    </view>
</template>
<script>
    export default {
        name: "diaglog",
        data(){
            return {
                param:{
                    title:'',
                    content:'',
                    cancelText:'取消',
                    cancelColor:'#333',
                    confirmText:'确定',
                    confirmColor:'#1ED58F',
                }
            }
        },
        onLoad(option) {
            // 将参数转换成json
            const data = JSON.parse(option.data)
            if(data){
                this.param = {...this.param,...data}
            }
        },
        methods: {
            cancelClick() {
                uni.$emit('$dialog', false)
                uni.navigateBack()
            },
            confirmClick() {
                uni.$emit('$dialog', true)
            }
        }
    }
</script>
<style lang="scss">
    page {
        width: 100%;
        height: 100%;
        background: rgba(0, 0, 0, 0);
    }

    .diaglog-mask {
        position: fixed;
        z-index: 1000;
        width: 100%;
        height: 100%;
        left: 0;
        top: 0;
        background-color: rgba(0, 0, 0, .23);
    }

    .diaglog {
        position: fixed;
        width: calc(100% - 80rpx);
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        background-color: #fff;
        padding-bottom: 0;
        box-sizing: border-box;
        z-index: 1001;
        border-radius: 20rpx;
        overflow: hidden;

        &-title {
            padding-top: 60rpx;
            padding-bottom: 30rpx;
            font-weight: bold;
            font-size: 32rpx;
            color: #333333;
            text-align: center;
        }

        &-content {
            font-weight: 500;
            font-size: 28rpx;
            color: #333333;
            line-height: 40rpx;
            padding: 0 40rpx;
            padding-bottom: 60rpx;
        }

        &-btns {
            display: flex;
            position: relative;

            &:before {
                position: absolute;
                content: '';
                width: calc(100% - 80rpx);
                left: 40rpx;
                height: 1rpx;
                background-color: #ECECEC;
            }

            &-button {
                flex: 1;
                text-align: center;
                height: 100rpx;
                line-height: 100rpx;
                font-weight: bold;
                font-size: 30rpx;
                color: #333333;

                &:first-child {
                    border-right: solid 1rpx #ECECEC;
                }

                &:active {
                    background-color: #f1f1f1;
                }
            }
        }
    }
</style>

在pages.json中加入页面

// 全局弹窗
{
    "path": "components/diaglog/diaglog",
    "style": {
        "navigationStyle": "custom",
        "app-plus": {
            "animationType": "fade-in", // 设置fade-in淡入动画,为最合理的动画类型
            "background": "transparent", // 背景透明
            "backgroundColor": "transparent", // 背景透明
            "webviewBGTransparent": true,
            "mask": "none",
            "popGesture": "none", // 关闭IOS屏幕左边滑动关闭当前页面的功能
            "bounce": "none" // 将回弹属性关掉
        }
    }
}

新建plugins目录,创建dialog.js

const install = Vue => {
    Vue.prototype.$dialog = (params) => {
        return new Promise((resolve, reject) => {
            // 防止当前页也是dialog
            if (getCurrentPages()[getCurrentPages().length - 1].route == 'components/diaglog/diaglog'){
                reject()
                return
            }
            // 跳转到dialog,并且传递title,content等参数
            uni.navigateTo({
                url: '/components/diaglog/diaglog?data=' + encodeURIComponent(JSON.stringify(
                    params))
            })
            // 注册一个回调
            uni.$once('$dialog', (state) => {
                if (state) {
                    resolve(() => {
                        uni.navigateBack()
                    })
                    return
                }
                reject()
            })
        })
    }
}
export default install;

在main.js中use插件

import dialogPlugin from '@/plugins/dialog';
Vue.use(dialogPlugin);

使用:

this.$dialog({
    title: '用户协议和隐私政策',
    content: '我们非常重视用户隐私政策并严格遵守相关的法律规定。请您仔细阅读<span style="color:#1ED58F">《隐私政策》</span>后再继续使用。如果您继续使用我们的服务,表示您已经充分阅读和理解我们协议的全部内容。并严格遵守相关的法律规定。请您仔细阅读并严格遵守相关的法律规定。请您仔细阅读。',
    cancelText: '不同意',
    confirmText: '同意',
}).then(()=>{
    // 确认后
}).catch(()=>{
    // 取消后
})

看效果

vue 做一个插件plugin 插件的创建(install)及使用方法 openvpn 设置外网流量走本地,异地组网流量走openvpn
biu biu biu
yarn 设置淘宝镜像 yarn 错误There appears to be trouble with your network connection. Retrying... win11 安装限制去除 跳过TPM CPU检测 附软件 win11 桌面不满足要求水印去除 适用于跳过TPM CPU检测安装后的桌面水印 php正则获取网页中的json update批量修改 mysql update select 用法实例