背景:接上篇app打包后地图无法加载出来,使用web-view解决此问题后又发现一个新问题,就是打包后地图上的弹窗也无法正常显示,地图后续开发中大量功能需要使用弹窗,不得不赶快解决这个问题。

解决:查阅官方文档后发现web-view组件在App和小程序中层级较高,组件默认铺满全屏并且层级高于前端组件,如需要在vue页面中写代码为web-view组件覆盖内容,只能由web-view的组件自己弹出div,App端里比较好的解决方式就是使用原生子窗体subNvue解决地图中的层级问题。

subNvue:subNVuevue 页面的子窗体,它不是全屏页面,就是用于解决 vue 页面中的层级覆盖和原生界面自定义用的。它也不是组件,就是一个原生子窗体。

1、页面结构

建议 subNVue 子窗体与引用该子窗体的vue页面放在同一目录下

|-- pages  
    |-- index               // index 目录  
    |   |-- subNVue         // subNVue 目录  
    |       |-- nav.nvue    // 自定义导航栏  
    |       |-- popup.nvue  // 弹出层子窗体  
    |-- index.vue           // index 页面

2、pages.json 配置

  • id: [String], 全局唯一,不能重复

  • path: [String], subNVue 子窗体的路径。

  • type: [String], 内置的特殊子窗体类型,弹出(popup)和导航(navigationBar)。

  • style: [Object], 配置子窗体的位置,背景等样式属性。

{  
    "pages": [{  
        "path": "pages/index/index", //首页  
        "style": {  
            "app-plus": {  
                "subNVues":[{  
                    "id": "concat", // 唯一标识  
                    "path": "pages/index/subnvue/concat", // 页面路径  
                    /*"type": "popup",  这里不需要*/  
                    "style": {  
                        "position": "absolute",  
                        "dock": "right",  
                        "width": "100rpx",  
                        "height": "150rpx",  
                        "background": "transparent"  
                    }  
                }]  
            }  
        }  
    }]  
}

3、获取subNVue 子窗体

  • 在页面中打开和关闭 subNVue 子窗体

// 通过 id 获取 nvue 子窗体  
const subNVue = uni.getSubNVueById('map_widget')  
// 打开 nvue 子窗体  
subNVue.show('slide-in-left', 300, function(){  
    // 打开后进行一些操作...  
    //   
});  
// 关闭 nvue 子窗体  
subNVue.hide('fade-out', 300)
  • 动态修改 subNVue 子窗体位置,大小

subNVue.setStyle({  
    top: '100px',  
    left: '20px',  
    width: '100px',  
    height = '50px',  
})

4、subNVue 子窗体与 vue页面通信

// 在 subNVue/vue 页面注册事件监听方法  
// $on(eventName, callback)  
uni.$on('page-popup', (data) => {  
    vm.title = data.title;  
    vm.content = data.content;  
})  

// 在 subNVue/vue 页面触发事件  
// $emit(eventName, data)  
uni.$emit('page-popup', {  
    title: '我是一个title',  
    content: '我是data content'  
});