uniapp 微信小程序封装全局弹框(登录拦截)

 

 

 

 

新增组件页面: loginProp.vue

<template>
    <view class="login-box" v-if="loginShow">
        <view class="center-box">
            <image class="logo" src="../../static/images/logo.png"></image>
            <view class="close" @tap="closeLogin">
                <u-icon name='close' color="#bebebe" size="26"></u-icon>
            </view>
            <view class="title">登录即可体验完整功能</view>
            <view class="btn-group">
                <view class="invite-specia" @tap="goLogin">
                    <u-icon name="weixin-fill" color="#fff" size="30"></u-icon>
                    <view style="margin-left: 20rpx;">
                        微信用户一键登录
                    </view>
                </view>
            </view>
        </view>
        <uni-popup ref="popup">
            <view class="login_phone_box">
                <view class="check_box">
                    <u-radio-group v-model="currentCheck" placement="row">
                        <u-radio :customStyle="{marginRight: '8px'}" v-for="(item, index) in radiolist" :key="index"
                            activeColor="#fc742a" :label="item.name" :name="item.value" @change="radioChange">
                        </u-radio>
                    </u-radio-group>
                </view>
                <view class="title">为了验证用户登录信息,小程序将获取您的手机号</view>
                <view class="operate">
                    <button class="login" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">登录</button>
                </view>
            </view>
        </uni-popup>
    </view>

</template>

<script>
    export default {
        name: 'login',
        props: ['loginShow'],
        data() {
            return {
                show: this.loginShow,
                sessionKey: {},
                wxCode: ''
            }
        },

        mounted() {},
        methods: {
            closeLogin() {
                this.$emit('closeLogin', this.show);
            },
            goLogin() {
                let _this = this;
                uni.login({
                    provider: "weixin",
                    success: (res) => {
                        // console.log('获取code', res);
                        if (res.errMsg.indexOf("ok") != -1) {
                            this.wxCode = res.code;
                            uni.showModal({
                                title: '温馨提示',
                                content: '亲,授权微信登录后才能正常使用小程序功能',
                                success(res) {
                                    //如果用户点击了确定按钮
                                    if (res.confirm) {
                                        uni.getUserProfile({
                                            desc: '获取你的昵称、头像、地区及性别',
                                            success: (res) => {
                                                // console.log('获取code', res);
                                                let _res = _this.$myRequset({
                                                    url: "api?operate=normal.user.WxDecode",
                                                    method: "POST",
                                                    data: {
                                                        code: _this.wxCode,
                                                        encryptedData: res
                                                            .encryptedData,
                                                        iv: res.iv,
                                                        signature: res
                                                            .signature,
                                                        rawData: res.rawData
                                                    },
                                                }).then((res) => {
                                                    _this.sessionKey = res.data
                                                        .data;
                                                });
                                                _this.$refs.popup.open();
                                                _this.getPhoneNumber();
                                            },
                                            fail: res => {
                                                console.log('fail', res);
                                                //拒绝授权
                                                uni.showToast({
                                                    title: '您拒绝了请求,不能正常使用小程序',
                                                    icon: 'none',
                                                    duration: 2000
                                                });
                                                return;
                                            }
                                        });
                                    } else if (res.cancel) {
                                        //如果用户点击了取消按钮
                                        // console.log(3);
                                        uni.showToast({
                                            title: '您拒绝了请求,不能正常使用小程序',
                                            icon: 'error',
                                            duration: 2000
                                        });
                                        uni.switchTab({
                                            url: "../index/index"
                                        });
                                        return;
                                    }
                                }
                            });
                        }
                    }
                });
            },
            /* 用户授权手机号 */
            async getPhoneNumber(e) {
                let _this = this;
                try {
                    let _msg = e.detail.errMsg;
                    if (_msg == "getPhoneNumber:ok") {
                        // 获取手机号
                        _this.$refs.popup.close();
                        _this.isLogin = true;
                        let _param = {
                            encryptedData: e.detail.encryptedData,
                            iv: e.detail.iv,
                            sessionKey: this.sessionKey.session_key,
                            openid: this.sessionKey.openid,
                            avatarUrl: this.sessionKey.avatarUrl,
                            nickName: this.sessionKey.nickName,
                            gender: this.sessionKey.gender,
                            login_type: this.currentCheck // 登录类型
                        }

                        let _url = $requestApi.get_phone;
                        console.log('$requestApi', _url);
                        this.$myRequset({
                            url: _url,
                            method: "POST",
                            data: _param,
                        }).then((res) => {
                            if (res.data.code == 1) {
                                uni.showLoading({
                                    title: '正在登录...'
                                });
                                _this.updateUserInfo(res.data.data);
                            } else {
                                uni.showToast({
                                    title: '登录失败',
                                    icon: 'error',
                                    duration: 2000
                                });
                            }
                        }).catch((err) => {
                            uni.showToast({
                                title: '登录请求失败',
                                icon: 'error',
                                duration: 2000
                            });
                            console.log("request_err", err);
                        });

                    } else {
                        // 重新要求授权
                    }
                } catch {}
            },
            //更新用户信息
            updateUserInfo(_token) {
                this.$myRequset({
                    url: "api?operate=normal.user.user_info",
                    method: "POST",
                    data: {
                        token: _token
                    }
                }).then((_res) => {
                    uni.showLoading({
                        title: '正在登录...',
                        icon: 'loading'
                    });
                    if (_res.data.code == 1) {
                        let userInfo = _res.data.data;
                        uni.setStorageSync('userInfo', userInfo);
                  setTimeout(function() {
                                    let pages = getCurrentPages(); //获取所有页面的数组对象
                                    console.log('pages',pages);
                                    let currPage = pages[pages.length - 1]; //当前页面
                                     currPage.onLoad(currPage.options); // 传入参数刷新当前页面
                                     currPage.onShow();
                                     currPage.onReady();      
                                    
                                    /* uni.reLaunch({  // 此方法不可行,当需要登录的页面带有参数时,relaunch会跳转首页,并不会重载当前页面
                                        url: currPage.$page.fullPath
                                    }); */
                        }, 1000);

 


                    } else {
                        uni.showToast({
                            title: _res.data.msg,
                            icon: "success",
                        });
                    }
                }).catch((err) => {
                    console.log("request_err", err);
                });
            },
        }
    }
</script>

<style scoped lang='scss'>
    .login-box {
        position: fixed;
        top: 0;
        left: 0;
        width: 100vw;
        height: 100vh;
        background: rgba(0, 0, 0, 0.5);
        z-index: 9999;

        & .center-box {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 622rpx;
            padding: 60rpx 32rpx;
            border-radius: 16rpx;
            opacity: 1;
            background: rgba(255, 255, 255, 1);

            .logo {
                position: absolute;
                top: -24rpx;
                left: 50%;
                transform: translateX(-50%);
                width: 90rpx;
                height: 100rpx;
            }

            .close {
                position: absolute;
                top: 24rpx;
                right: 24rpx;
                width: 48rpx;
                height: 48rpx;
            }

            .title {
                margin: 66rpx 0 40rpx;
                text-align: center;
                color: rgba(0, 0, 0, 1);
                font-size: 36rpx;
                font-weight: 500;
                font-family: "PingFang SC";
                letter-spacing: 0.6rpx;
            }

            .content {
                margin: 40rpx 0;
                font-size: 30rpx;
                font-family: "PingFang SC";
                letter-spacing: 0.6rpx;
                color: #212121;
                text-align: center;

                text {
                    font-size: 32rpx;
                    letter-spacing: 0.6rpx;
                    color: rgba(69, 108, 255, 1);
                }
            }

            .btn-group {
                display: flex;
                justify-content: center;
                padding: 0 16rpx;

                .invite-specia {
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    width: 526rpx;
                    height: 88rpx;
                    line-height: 88rpx;
                    border-radius: 16rpx;
                    text-align: center;
                    background: linear-gradient(-46.8deg, #34aa3a 0%, #2d9432 100%);
                    color: #fff;
                }
            }
        }
    }


    /* 获取手机号 */
    .login_phone_box {
        padding: 40rpx 30rpx 80rpx;
        background-color: #fff;
        border-radius: 12rpx;
        width: 75%;
        margin: 0 auto;

        & .title {
            font-size: 34rpx;
            color: #7d7d7d;
            margin: 0;
            margin-bottom: 60rpx;
            letter-spacing: unset;
        }

        & .operate {
            display: flex;
        }

        & button {
            border: none;
            font-size: 32rpx;
            color: #000;
            background-color: #f5f5f5;
            border-radius: 8rpx;
            width: 200rpx;
            padding: 0;
            height: 80rpx;
            line-height: 80rpx;
            border-color: transparent;
            outline: unset;

            &.login {
                background-color: #fc742a;
                color: #fff;
            }
        }
    }
</style>

 

 

页面使用:先引入组件,当组件来使用(loginShow决定啥时候显示,啥时候隐藏)

<template>
    <view class="pages">
        <view>
            <view class="top">
                <view class="flex">
                    <image :src="userInfo.avatar" v-if="userInfo"></image>
                    <image v-else src="../../static/images/default.png"></image>
                    <view class="flex_cloumn" v-if="userInfo">
                        <text class="title">{{userInfo.name}}</text>
                    </view>
                    <view v-else @tap="goLogin">
                        <u--text text="登录" size="18"></u--text>
                    </view>
                </view>
            </view>
            <view class="bottom">
                <view class="tab_box">
                    <view class="item" @tap="goPage('info')">
                        <text class="title">编辑资料</text>
                        <u-icon name="arrow-right" size="24"></u-icon>
                    </view>
                </view>
            </view>
            <view class="operate_box" v-if="userInfo">
                <button @tap="toLogout">退出登录</button>
            </view>
        </view>
        <loginProp :loginShow="loginShow" @closeLogin="closeLogin"></loginProp>
    </view>
</template>

<script>
    import loginProp from "../../components/login/loginProp.vue";
    export default {
        name: "personal",
        components: {
            loginProp
        },
        data() {
            return {
                loginShow:false, //登录弹框
                userInfo: {}
            }
        },
        onShow() {
            this.userInfo = this.checkLogin();
            console.log('userInfo', this.userInfo);
        },
        onPullDownRefresh() {

        },
        onLoad() {
            this.initData();
        },
        methods: {
            closeLogin(){
                this.loginShow = false;
            },
            
            /* 初始化页面数据 */
            initData() {

            },
            /* 修改排序 */
            changeSort(_index) {
                this.currentSort = _index;
                this.$refs.popup_sort.open();
            },
            /* 修改在线状态 */
            goPage(_type) {
                let _url = '';
                switch (_type) {
                    case 'info': // 编辑资料
                        _url = "../../pageA/myDetail/myDetail";
                        break;
                }
                uni.navigateTo({
                    url:_url
                })
            },
            goLogin(){
                this.loginShow = true;
            },
            /* 快速进去会话 */
            changeChatin() {},
            toLogout() {
                let _this = this;
                let context = {
                    loading_title: "正在退出...",
                    content: "确定退出登录吗?",
                    cancel: "取消退出"
                };
                uni.showModal({
                    title: '温馨提示',
                    content: context.content,
                    success: (res) => {
                        if (res.confirm) {
                            _this.$myRequset({
                                url: this.$requestApi.logout,
                                data: {
                                    token: _this.userInfo.token
                                }
                            }).then((res) => {
                                if (res.data.code == 1) {
                                    uni.showLoading({
                                        title: context.loading_title
                                    });
                                    setTimeout(function() {
                                        uni.removeStorageSync('userInfo');
                                        uni.reLaunch({
                                            url: "../index/index"
                                        });
                                        uni.showToast({
                                            title: res.data.msg,
                                            icon: "none"
                                        });
                                        uni.hideLoading();
                                    }, 2000);
                                } else {
                                    uni.showToast({
                                        title: res.data.msg,
                                        icon: "error"
                                    });
                                }
                            }).catch((err) => {
                                console.log("request_err", err);
                            });

                        } else if (res.cancel) {
                            uni.showToast({
                                title: context.cancel,
                                icon: "none"
                            })
                        }
                    }
                })
            }
        }
    }
</script>

<style lang="scss">
    @import url("personal.css");
</style>

 

这个只能说是使用公共组件的方式了,网上有解决方案,是使用dom挂载全局的方式,但是不能使用正常js追加dom元素的方式,小程序不支持document.appensChild的方式。

 

 

 


具体实现方式请查看: https://blog.csdn.net/jsmeng626/article/details/125338447,这个方式是没办法全局挂载的,目前我没找到解决方案。。。如果有大佬能有更好的解决方案麻烦评论区告知下哦,互相交流,谢谢!

posted on 2022-08-29 15:33  小虾米吖~  阅读(7339)  评论(0编辑  收藏  举报