uniapp webview官方地址uniapp.dcloud.net.cn/component/w…
uni.webview.1.5.4.js下载地址 gitee.com/dcloud/uni-…
案例一:原生h5嵌入(这个比较粗略)
注意下面的代码,如果想把静态页面放在app代码一起,静态文件最好放在static文件下,要不然app可能会出错,如下
留意两个文件的receiveData必须是一致
<template>
<web-view ref="webview" src="/static/HTML/index.html" @message="handleMessage"></web-view>
</template>
<script setup>
import { ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
const webview = ref(null);
const vw = ref(null);
//----------------------------------------- 获取子应用 发送数据
function getVw() {
// 找到路由栈里的最后一位 仅app支持,api见https://uniapp.dcloud.net.cn/tutorial/page.html#getappwebview
const pages = getCurrentPages();
vw.value = pages[pages.length - 1].$getAppWebview().children()[0];
let params = [{
msg:"这是信息"
}];
vw.value.evalJS(`receiveData(${JSON.stringify(params)})`);
}
onLoad(() => {
// 如果是页面初始化调用时,需要延时一下
setTimeout(() => {
getVw();
}, 1000);
});
//-------------------------------------------接收数据
function handleMessage(msg) {}
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
/>
<title>啦啦啦</title>
<script src="./js/uni.webview.1.5.4.js"></script>
<script src="./css/index.css"></script>
</head>
<body>
<div className="demo">
</div>
<script>
// 接收外层传进来的数据
function receiveData(data) {
creatlink("video-container", data);
}
//发送数据
function handleClick () {uni.postMessage({data: {msg: '啦啦啦'}})}
</script>
</body>
</html>
案例二:uniapp h5嵌入
<template>
<web-view
v-if="src"
:src="src"
@message="handleMessage"
:style="{ 'background-color': safeBg }"
></web-view>
</template>
<script setup>
import { ref } from "vue";
import { onShow, onHide, onLoad } from "@dcloudio/uni-app";
const src = ref("");
const wv = ref(null);
let height = 0; //定义动态的高度变量
let statusbar = 0; // 动态状态栏高
onLoad(() => {
/*#ifdef APP-PLUS*/
uni.getSystemInfo({
// 获取当前设备的具体信息
success: (sysinfo) => {
// 嵌入页面关闭uniapp的默认导航头部,且本页未开启默认导航头 的情况
statusbar = sysinfo.statusBarHeight;
height = sysinfo.windowHeight;
// 嵌入页面开启uniapp默认导航头部的情况,且本页开启默认导航头 的情况
// 这样可以做到单独访问嵌入页也能有导航头
// statusbar = sysinfo.statusBarHeight;
// height = sysinfo.windowHeight + sysinfo.windowHeight;
},
});
//这里一定要延迟
setTimeout(() => {
const pages = getCurrentPages();
wv.value = pages[pages.length - 1].$getAppWebview().children()[0];
//给嵌入页发送信息
wv.value.evalJS(
`receiveData(${JSON.stringify({
msg: "哈哈哈哈哈哈哈哈哈哈哈哈哈",
})})`
);
wv.value.setStyle({
top: statusbar,
height: height,
});
}, 1000);
//监听软键盘出现
if(plus.os.name !== "iOS"){
uni.onKeyboardHeightChange((res) => {
if (res.height == 0) {
wv.value.setStyle({
top: statusbar,
height: height,
});
} else {
wv.value.setStyle({
top: statusbar ,
height: height - res.height,
})
}
});
}
/*#endif*/
src.value = `这是嵌入的H5地址?token=11111`;
console.log(src.value);
/*#ifdef H5*/
window.addEventListener("message", handleMessage, false);
/*#endif*/
});
onShow(() => {
if (wv.value) {
//给嵌入页发送信息
wv.value.evalJS(
`receiveData(${JSON.stringify({
msg: "哈哈哈哈哈哈哈哈哈哈哈哈哈",
})})`
);
}
});
const safeBg = ref("#fff");
function handleMessage(msg) {
// console.log("收到消息————————————————————————", msg);
let getdata;
/*#ifdef APP-PLUS*/
getdata = msg.detail.data[0];
/*#endif*/
/*#ifdef H5*/
getdata = msg.data.data.arg;
/*#endif*/
console.log("web-view收到消息", getdata.msg);
//这里举例几个很常用的场景
//多见于嵌入页内还要切换的场景 或
//嵌入页的导航头为自定义(需要修改上面空出来安全距离的颜色)
switch (getdata.msg) {
case "tabbar隐藏":
uni.hideTabBar({
animation: true,
});
/*#ifdef APP-PLUS*/
wv.value.setStyle({
top: statusbar,
height: height
});
/*#endif*/
break;
case "tabbar出现":
uni.showTabBar({
animation: true,
});
/*#ifdef APP-PLUS*/
wv.value.setStyle({
top: statusbar,
height: height - 50,//tabbar的默认高度为50
});
/*#endif*/
break;
case "改变顶部安全距离颜色":
safeBg.value = getdata.color;
break;
default:
break;
}
}
onHide(() => {
// #ifdef APP-PLUS
// 取消监听键盘高度
uni.offKeyboardHeightChange((res) => {});
// #endif
});
</script>
<style scoped lang="scss"></style>
嵌入页代码的App.vue中,加入如下代码
<script>
export default {
onLaunch: function () {
console.log("WEB onLaunch", location.href);
//不需要登录的页面
const white = ["/pages/PrivacyAgreement/index"]
if (white.includes(location.href.split('#')[1])) {
return
}
//需要登录的页面
function getUrlKey(name, url) {
let getdata =
decodeURIComponent(
(new RegExp("[?|&]" + name + "=" + "([^&;]+?)(&|#|;|$)").exec(
url
) || [, ""])[1].replace(/\+/g, "%20")
) || undefined;
if (getdata == "undefined" || getdata == undefined) {
return "";
}
return getdata;
}
// 设置token,权限获取
const token = getUrlKey("token", location.href);
if (token) {
console.log("取到token为",token);
// 取到token,设置本地存储和状态存储
} else {
//为什么要这么做,因为如果杀后台的话,到子页面就成了第一页无法再次返回,再做返回的处理很麻烦,干脆手动返回首页
uni.reLaunch({
url: "/pages/index/index",
});
}
},
onShow: function () {},
onHide: function () {},
};
window.receiveData = function (data) {
console.log("接收外层传进来的数据", data.msg);
//接收数据,刷新数据等操作
};
</script>
如果嵌入页想向父页发送消息,如下,至于为什么是webuni.而不是uni.见最下面的注意
这个引入一定要在入口文件main.js引入,要不然打包会报错(webuni 找不到)
import '@/utils/uni.webview.1.5.4.js'
webuni.postMessage({data: {msg: '啦啦啦'}})
注意!!!!
①语言平台差异
如果web页面是uniapp开发的,那么uni.webview.1.5.4.js这个文件需要修改,将以下3个地方的uni改成你习惯的,如webuni,如下图
然后使用是将 如
uni.postMessage({data: {msg: '啦啦啦'}})改成 webuni.postMessage({data: {msg: '啦啦啦'}})
②H5和app平台差异
Ⅰ、网页调试时,<web-view ref="webview" src="/static/HTML/index.html" @message="handleMessage"></web-view>中的@message是不生效的,要使用window.addEventListener("message", handleMessage, false);
文档来源developer.mozilla.org/zh-CN/docs/…
Ⅱ、function handleMessage(msg) {}这个代码中,H5和app返回的msg是不一样的,具体自己调试看看