解决方案

uniapp|原生控件层级过高无法覆盖的解决方案

作者:仙宝云 | 发布时间:2021-06-02 13:43:18 | 阅读:212

原生组件说明

小程序和App的vue页面,主体是webview渲染的为了晋升性能,小程序和App的vue页面下局部ui元素,比如导航栏、tabbar、video、map应用了原生控件这种方法被称为混杂渲染

虽然晋升了性能,但原生组件带来了其他题目:

  • 前端组件回天乏术掩盖原生控件的层级题目
  • 原生组件不能嵌入特殊前端组件(假如scroll-view)
  • 原生控件ui回天乏术灵敏自定义
  • 原生控件在Android上,字体会见渲染为rom的主题字体,而webview如果不经过单独改造不会应用rom主题字体

H5、App的nvue页面,不存在混合渲染的情形,它们或者全体是前端渲染、或者全体是原生渲染,不波及层级题目

uni-app 中原生组件清单如下:

  • map
  • video
  • camera(仅微信小程序、百度小程序支撑)
  • canvas(仅在微信小程序、百度小程序表现为原生组件)
  • input(仅在微信小程序、支付宝小程序、字节跳动小程序、QQ小程序中且input购置焦经常表现为原生组件,其中支付宝小程序的input仅为text且购置焦常常才表现为原生组件)
  • textarea(仅在微信小程序、百度小程序、字节跳动小程序表现为原生组件)
  • live-player(仅微信小程序、百度小程序支撑,App端直接利用video组件但是同时实现拉流)
  • live-pusher(仅微信小程序、百度小程序、app-nvue撑持,app-vue利用plus.video.LivePusher但是实现推流)
  • cover-view
  • cover-image

夹杂渲染模式下原生组件的使用限制

由于原生组件脱离在 WebView 渲染流程外,因此在运用不时有以下限制:

  • 原生组件的层级是最高的,所以页面中的其他组件无论设置 z-index 为多少,都回天乏术盖在原生组件上后插入的原生组件可以掩盖之前的原生组件
  • 原生组件回天乏术在 scroll-view、swiper、picker-view、movable-view 中应用
  • 同层渲染支持:微信基础库2.4.4起撑持了video的同层渲染、微信基础库2.8.3撑持map的同层渲染撑持同层渲染后,相关组件的时分不再有层级题目,无需再使用cover-view掩盖,也可以内嵌入swiper等组件app-nvue 不波及层级题目,天然所有组件都是同层渲染
  • 局部CSS样式回天乏术应用于原生组件,例如:

回天乏术对原生组件设置 CSS 动画;

回天乏术界说原生组件为 position: fixed;

不能在父级节点利用 overflow: hidden 来裁剪原生组件的显示区域。

  • 在小程序端真机上,原生组件会面遮挡 vConsole 弹出的调试面板

其他原生界面元素

除了原生组件外,uni-app在非H5端还有其他原生界面元素,清单如下:

  • 原生navigationBar和tabbar(pages.json里配置的)
  • web-view组件虽然不是原生的,但这个组件相当于一个原生webview掩盖在页面上,并且小程序上web-view组件是强制全屏的,回天乏术在上面掩盖前端元素
  • 弹出框:picker、showModal、showToast、showLoading、showActionSheet、previewImage、chooseImage、chooseVideo等弹出元素也回天乏术被前端组件掩盖
  • plus下的plus.nativeObj.view、plus.video.LivePusher、plus.nativeUI、plus.webview,层级均高于前端元素

留神:app的nvue页面里的组件虽然不波及map、video等原生组件的层级遮挡题目,但pages.json中配置的原生tabbar、原生navigationBar,一样是nvue里的组件也回天乏术遮挡的

vue页面层级掩盖解决方案

为了解决webview渲染中原生组件层级最高的限制,uni-app提供了 cover-view 和 cover-image 组件,让其掩盖在原生组件上

除了跨端的cover-view,App端还提供了3种方案:plus.nativeObj.view、subNVue、新开半透明nvue页面详述如下

  • cover-view

cover-view只能掩盖原生组件,不能掩盖其他原生界面元素比如cover-view可以掩盖video、map,但回天乏术掩盖原生导航栏、tabbar、web-view

微信小程序在基础库 2.4.0 起已支撑 video 组件的同层渲染,2.7.0 起支持 map 组件的同层渲染可以被前端元素通过调节zindex来遮挡,也支撑在scroll-view等组件中内嵌这2个原生组件但video全屏不时,仍需要cover-view覆盖。

app-vue的cover-view相比小程序端还有一些限制,

1) 回天乏术嵌套

2) 回天乏术内部滚动,纵然cover-view回天乏术内部出现滚动条、

3) 回天乏术掩盖到视频的全屏界面 app-nvue的cover-view不管这些限定

另外cover-view无论如何都回天乏术解决原生导航栏、tabbar、web-view组件的覆盖,为此App端增补了2个层级覆盖方案plus.nativeObj.view和subNVue

  • plus.nativeObj.view

简称nview,它是一个原生的近似画布的控件,其实cover-view也是用plus.nativeObj.view封装的API文档详见:https://www.html5plus.org/doc/zh_cn/nativeobj.html#plus.nativeObj.View

plus.nativeObj.view的API比较原生,可以绘出任何界面,但plus.nativeObj.view有3个题目:

1. api很底层,开发比较复杂;

2. 不撑持动画;

3. 不撑持内部滚动

  • subNVue

subNVue是原生渲染的nvue子窗体,把一个nvue页面以半屏的方法掩盖在vue页面上它解决了plus.nativeObj.view的不足,提供了强大的层级题目解决方案subNVue的详细介绍见:https://ask.dcloud.net.cn/article/35948

  • 弹出局部区域透明的nvue页面

uni-app支撑在App端弹出半透明的nvue窗体即看起来是在本窗体弹出一个元素,但实际上是弹出了一个局部区域蒙灰透明的新窗体这样的窗体比subnvue有个优势就是可以全局复用具体参考这个插件

subNVue或弹出局部区域透明的nvue页面,会晤比plus.nativeObj.view多占用一些内存。所以如果你如果掩盖的内容很简单,cover-view或plus.nativeObj.view可以简略实现的话,就没必要用subNVue或nvue

所以如果你的层级覆盖题目比较简略,不用嵌套,且有跨端需求,就利用cover-view

如果App端cover-view回天乏术满足需求,且需要覆盖的原生界面比较简略,可以用plus.nativeObj.view否则,就应用subnvue或局部区域透明的nvue吧

关于subNVue和Webview的层级题目 subNVue的层级高于前端元素,但大都个subNVue以及Webview,它们之间的也存在层级关联

默认规则是,先创立的subNVue或webview在底部,后创立的会晤盖住之前的

当然每个subNVue和webview,都撑持Style参数配置,其中有一个zindex属性,可以调节它们的层级

App的nvue页面层级题目

nvue页面全部都是原生组件,互相之间没有层级题目

但如果在pages.json里注册了原生导航栏和tabbar,nvue里的界面元素默认也回天乏术掩盖这些,也需要plus.nativeObj.view或subNVue

如果仅开发App,不跨端,不愿波及层级题目,也可以不利用pages.json里的原生导航栏和tabbar,nvue页面不需要这些来强化性能。

智慧商业服务商仙宝云欢迎您!

请加微信: 18962171986 (宋经理)

在线咨询