关于web-view组件层级过高导致其它视图组件不可视的解决办法


需求

当点击左边红色框内的单号时,右边黄色框展示区域显示对应的信息(视频或者PDF)。如果该单号同时存在视频或者PDF,则绿色框单选按钮组显示视频和PDF单选框,如果只存在一种则只显示一种单选框。

实现

布局如下

<template>
	<view class="pageContainer">
		<view class="sidebar">
			<h3 class="orderHeader"><text>生产单号</text><u-button icon="reload" @click="getOrderList"></u-button></h3>
			<ul v-if="hasOrder" class="orderList">
				<li v-for="(item,index) in orderList" :key="index" :class="{active: activeOrder === index}"
					@click="clickOrder(item, index)"><text>{{item}}</text></li>
			</ul>
			<u-empty v-else mode="list" iconSize="36" marginTop="20"></u-empty>
		</view>
		<view class="displayArea">
			<template v-if="sopInfo.isExist">
				<video v-if="radioValue === 'video'" style="width: 100%;height: 100%;" :src="sopUrl" controls loop
					autoplay></video>
				<scroll-view style="height: 100%;" v-if="radioValue === 'pdf'" scroll-y="true">
					<web-view :src="sopUrl" :update-title="false" :webview-styles="webviewStyles"></web-view>
				</scroll-view>
			</template>
			<dataNull v-else title="暂无相关资料~"></dataNull>
		</view>
		<!-- #ifdef H5 -->
		<u-radio-group class="modeGroup" placement="row" v-model="radioValue" @change="changeRadio">
			<template v-for="(r, i) in radioList">
				<u-radio v-if="r.show" :customStyle="{marginLeft: '16px'}" labelColor="white" :label="r.label"
					:name="r.name"></u-radio :key="i">
			</template>
		</u-radio-group>
		<!-- #endif -->
	</view>
</template>

注意1

右边黄色区域为一个 web-view 组件,web-view 是一个 web 浏览器组件,可以用来承载网页的容器,会自动铺满整个页面,nvue 使用需要手动指定宽高,即这里 webviewStyles

<script>
	export default {
		data() {
			return {
				webviewStyles: {
					width: '',
					height: '',
					top: '44px',
					left: '224px'
				}
            }
		},
    }
</script>

注意2

web-view组件在App和小程序中层级较高,如需要在vue页面中写代码为web-view组件覆盖内容,小程序端无解,只能由web-view的组件自己弹出div,官方文档提供了4种解决方法,这里用的是 plus.nativeObj.view

// radioList是一个存放单选框按钮组数据的数组
radioList.forEach((radio, index, list) => {
    radio.view = null   // 这里需把之前渲染的view对象清除
    radio.view = new plus.nativeObj.View(radio.name + 'View', {
        top: this.topDist + (index * 40) + 'px',
        left: this.leftDist + 'px',
        height: '30px',
        width: '60px',
        zIndex: '10'
    })
    radio.view.drawRect({
        color: that.radioValue === radio.name ? 'rgb(41, 121, 255)' : 'gray',
        radius: '10px'
    }, {
        top: '0px',
        left: '0px',
        width: '100%',
        height: '100%'
    }, radio.name)
    radio.view.drawText(radio.label, {}, {
        align: 'center',
        color: '#fff'
    })
    radio.view.addEventListener("click", function(e) {
        radio.view.drawRect({
            color: 'rgb(41, 121, 255)',
            radius: '10px'
        }, {}, radio.name)
        list[(index + 1) % 2].view.drawRect({
            color: 'gray',
            radius: '10px'
        }, {}, list[(index + 1) % 2].name)
        that.changeRadio(radio.name)
    }, false)
})
// 如果是存在视频/PDF就显示视频/PDF单选框(`.show()`),反之就隐藏(`.hide()`)
watch: {
    radioList: {
        deep: true,
        handler: function(newValue) {
            //#ifdef APP-PLUS
            newValue.forEach(item => {
                item.show ? item.view.show() : item.view.hide()
            })
            //#endif
        }
    }
},
// 页面销毁时记得清理
closePlusView() {
    //#ifdef APP-PLUS
    this.radioList.forEach(radio => {
        radio.view.close()
    })
    //#endif
},

文章作者: April-cl
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 April-cl !
  目录