subNVue用法参考:https://uniapp.dcloud.net.cn/api/window/subNVues.html#app-get...

有时候我们需要覆盖uniapp原生的tabbar或者其他的,这个时候就可以使用subNVue。
plus.nativeObj.view 虽然更灵活,但易用性比较差、没有动画、不支持内部内容滚动

首先需要在pages.json中配置

{
            "path": "pages/client/initiateElectronContract/index",
            "style": {
                "navigationBarTextStyle": "white",
                "navigationBarTitleText": "编辑电子合同",
                "navigationBarBackgroundColor": "#00bdbd",
                "backgroundColor": "#00bdbd",
                "navigationStyle": "custom",
                "app-plus": {
                    "subNVues": [
                        {
                            "id": "initiateContractShare", // 唯一标识  
                            "type": "popup",
                            "path": "pages/client/initiateElectronContract/subNVue/share",
                            "style": {
                                "position": "absolute",
                                "bottom": "0",
                                "left": "0",
                                "right": "0",
                                "width": "100%",
                                "height": "200px"
                            }
                        },
                        {
                            "id": "tips",
                            "type": "popup",
                            "path": "pages/client/initiateElectronContract/subNVue/popup"
                        }
                    ]
                }
            }
        },

popup.nvue文件

<template>
    <view class="page">
        <view class="shares">
            <view class="title">开始签约</view>
            <view class="content">
                <text class="tip">发起签约后,合同内容不能再次修改,同时会消耗一份合同的使用量,是否开始签约?</text>
            </view>
            <view class="operation">
                <view class="cancel btn" @click="cancel">
                    <text class="txt canceltxt">取消</text>
                </view>
                <view class="confirm btn" @click="confirm">
                    <text class="txt confirmtxt">确定</text>
                </view>
            </view>
            <view class="close" @click="cancel">
                <image src="../../../../static/close.png" style="width: 20px;height: 20px;" alt="close" />
            </view>
        </view>
    </view>
</template>

<script>
    export default {
        data() {
            return {
            };
        },
        created() {
            const vm = this;
            // 接收信息的页面
            // uni.$on('from-parent', (data) => {
            //     uni.showToast({
            //         title: data.type + ', ' +  data.content
            //     })
            //     switch (data.type) {
            //         case '1':
            //             break;
            //         case '2':
            //             break;
            //         case '3':
            //             break;
            //             // .... 
            //     }
            // });
        },
        beforeDestroy() {
            // 页面销毁之前 移除监听器
            // uni.$off('from-parent');
        },
        methods: {
            cancel() {
                // 获取当前 subNVues 原生子窗体的实例。
                const subNVue = uni.getCurrentSubNVue();
                // 子窗体隐藏
                subNVue.hide();
            },
            confirm() {
                // 获取当前 subNVues 原生子窗体的实例。
                const subNVue = uni.getCurrentSubNVue();
                // 向父窗体传递参数
                uni.$emit('to-parent', {
                    type: '3',
                    content: content
                });
                // 子窗体隐藏
                // 可自定义 隐藏动画效果,时间
                // subNVue.hide();
            },
        }
    }
</script>
<style>
    /* 分享弹窗 */
    .shares {
        height: 300px;
        font-size: 20upx!important;
        padding: 10px;
    }
    .title {
        width: 300px;
        display: flex;
        text-align: center;
        justify-content: center;
    }
    .tip {
        font-size: 16px;
        padding: 20px 0 10px;
    }
    .operation {
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
    }
    .btn {
        display: flex;
        justify-content: center;
        align-items: center;
        color: #606266;
        padding: 10px 30px;
    }
    .txt {
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 16px;
    }
    .close {
        position: absolute;
        top: 10px;
        right: 10px;
    }
</style>

index.vue文件

<template>
    <view class="initiateContract">
        <view class="html-box">
            <web-view :src="'../../../hybrid/html/viewContract/index.html?data=' + obj" ref="wv"></web-view>
        </view>
        
        <view class="footer">
            <view class="box">
                <view class="item">
                    <view class="btn">
                        <u-button type="primary" :key="1" :plain="true" text="保存合同"></u-button>
                    </view>
                </view>
                <view class="item" @click="share">
                    <view class="btn">
                        <u-button type="primary" :key="2" text="分享预览"></u-button>
                    </view>
                </view>
                <view class="item">
                    <view class="btn">
                        <u-button type="primary" :key="3" text="开始签约"></u-button>
                    </view>
                </view>
                <view class="item">
                    <view class="btn">
                        <u-button :disabled="true" :key="4" type="success" text="签约中"></u-button>
                    </view>
                </view>
            </view>
        </view>
    </view>
</template>

<script>
    export default {
        name: "electronContractEdit",
        data() {
            return {
                obj: null
            }
        },
        onLoad() {
            const vm = this;
            // 接收信息的页面(子窗体向父窗体传递参数)
            uni.$on('to-parent', (data) => {
                switch( data.type ){
                    case '1':
                        uni.setClipboardData({
                            data: this.shareImgInfo.result.tips,
                            success: function () {
                                console.log('success');
                                uni.showToast({
                                    icon: 'none',
                                    title: '链接已复制'
                                })
                            }
                        });
                        break;
                    case '2':
                        console.log('分享到微信')
                        break;
                }
            });
        },
        methods: {
            //方式一:打开id为initiateContractShare的nvue文件
            share() {
                const subNVue = uni.getSubNVueById('initiateContractShare'); //  对应page.json的id
                // 向子窗体传递参数
                // uni.$emit('from-parent',{
                //     type: '1',
                //     content: '父给子参数1'
                // })
                // 1:子窗体从顶部进入(动画效果), 2:显示原生子窗体的动画持续时间
                subNVue.show('slide-out-top', 300)
            },
            
            //方式二:打开id为tips的nvue文件
            openSubNVue() {
                const subNVue = uni.getSubNVueById('tips'); //  对应page.json的id
                // 向子窗体传递参数
                // uni.$emit('from-parent',{
                //     type: '1',
                //     content: '父给子参数1'
                // })
                
                // 1:子窗体从顶部进入(动画效果), 2:显示原生子窗体的动画持续时间
                subNVue.setStyle({    //在js中设置样式
                    "position": "absolute",
                    "width": "300px",
                    "height": "180px",
                    "margin": "auto",    //居中
                    "color": "#000000",
                    "background-color": "#FFFFFF",
                    "border-top-left-radius": "15px",
                    "border-top-right-radius": "15px"
                })
                subNVue.show('slide-out-top', 300)
            },
        },
        beforeDestroy() {
            // 页面销毁之前 移除监听器
            uni.$off('to-parent')
        },
    }
</script>

<style lang="scss" scoped>
    .initiateContract {
        .footer {
            position: fixed;
            bottom: 0px;
            left: 0px;
            right: 0px;
            z-index: 9999;
            padding: 10px 0 20px;
            background: #fff;
            border-top: 1px solid #f3f3f3;
            .box {
                display: flex;
                justify-content: space-around;
                align-items: center;
                .item {
                    .btn {
                        margin: 0 auto; 
                    }
                }
            }
        }
    }

</style>

这里设置nvue窗体位置的样式有两种方式,一种是在page.json中配置,另一种则是通过方法设置。


会说话的树
41 声望0 粉丝