html
<template>
<view class="container">
<!-- 1. WebView 组件 -->
<!-- 注意:不要在这里写 v-show,原生组件只认 v-if -->
<web-view
v-if="urlPath"
:src="urlPath"
@message="onWebViewMessage"
@load="onWebViewLoad"
></web-view>
<!-- 2. 加载过渡页:换回普通的 view,这样转圈动画才能生效 -->
<view v-if="showLoading" class="loading-mask">
<view class="loading-content">
<image class="logo" src="test.png" mode="aspectFit"></image>
<view class="spinner"></view>
<text class="loading-text">正在连接宠物问诊...</text>
</view>
</view>
</view>
</template>
javascriptonShow(){ //初始化当webview还未完全加载出的时候,首先拦截webview的出现 this.initAppWebview(); }, initAppWebview() { let retryCount = 0; // 轮询查找原生子节点 const timer = setInterval(() => { const pages = getCurrentPages(); const page = pages[pages.length - 1]; if (!page) return; const currentWebview = page.$getAppWebview(); const children = currentWebview.children(); // 一旦找到 web-view 的原生实例 if (children && children.length > 0) { clearInterval(timer); const wv = children[0]; // 1. 立即把它踢出屏幕外 (这就是 loading 遮盖不会被挡住的秘密) wv.setStyle({ top: '3000px', bottom: '-3000px' }); // 2. 赋予安卓特定权限 if (plus.os.name === 'Android') { const realWebView = wv.nativeInstanceObject(); if (realWebView) { const settings = realWebView.getSettings(); settings.setDomStorageEnabled(true); settings.setMediaPlaybackRequiresUserGesture(false); const WebChromeClient = plus.android.importClass('android.webkit.WebChromeClient'); const customClient = plus.android.implements('android.webkit.WebChromeClient', { "onPermissionRequest": function(request) { request.grant(request.getResources()); } }); realWebView.setWebChromeClient(customClient); } } } if (retryCount++ > 30) clearInterval(timer); // 轮询上限 }, 100); // 100ms 快速轮询 }, // 监听 H5 发来的渲染完毕消息 onWebViewMessage(e) { let msgData = e.detail.data; if (msgData && msgData.length > 0) { if (msgData[0].action === 'h5_ready') { console.log("收到 H5 通知,瞬间拉回 Webview"); this.showWebview(); } } }, // 兜底策略 onWebViewLoad() { console.log("H5 骨架加载完毕,启动兜底定时器..."); // 如果 4 秒后还没收到 h5_ready 消息,强制显示,防止死锁白屏 this.loadTimeout = setTimeout(() => { if (this.showLoading) { console.log("兜底触发,强制拉回"); this.showWebview(); } }, 4000); }以下是对应调用web-view的Html内容,待渲染完毕后给uniapp发消息已经渲染完成,通过
onWebViewMessage事件监听html发来的消息
javascript<script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script> <script> document.addEventListener('UniAppJSBridgeReady', function() { // 2. 假设这里是你请求接口渲染页面的逻辑 setTimeout(() => { // 模拟你的页面数据渲染完成了 // 3. 告诉 App:我渲染完了,你可以关掉 Loading 了! uni.postMessage({ data: { action: 'h5_ready' } }); }, 500); // 实际项目中,把 uni.postMessage 放在接口请求 then() 的最后 }); </script>