首先,让我们来谈谈应用的业务场景。大伙的业务场景是什么样我不知道,我来谈谈我踩坑时的业务场景。
老板:我们有个移动端的网页项目,但是为了唬客户,我们需要把这个网页打包成ios端和安卓端的app,页面中有一个需要调用摄像头的拍照签到功能。
我内心活动:ok,uni + webview没跑了,但是webview是不能直接调用手机的摄像头的,他的逻辑大概是,点击网页的签到按钮触发一个事件,事件给app发送一个我要使用手机摄像头的需求,然后再uni中收到了信号,去调起手机的摄像头。
所以,搞明白了业务场景,不管三七二十一,先上案例,看看最简单的demo咋实现。
html页面:
首先模拟一个网页,我们就用一个静态的html网页就好。webview要访问本地静态页面的话,静态页面是需要放在static目录底下的,在这我们命名为index.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>网页实时向APP发送消息</title>
<!-- uni 的 SDK,必须引用。 -->
<script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>
<!-- 微信 JS-SDK 如果不需要兼容小程序,则无需引用此 JS 文件。 -->
<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
</head>
<body>
<script type="text/javascript">
// 在引用依赖的文件后,需要在 HTML 中监听 UniAppJSBridgeReady 事件触发后,才能安全调用 uni 的 API。
document.addEventListener('UniAppJSBridgeReady', function() {
uni.getEnv(function(res) {
console.log('当前环境:' + JSON.stringify(res));
});
//向APP发送消息
uni.postMessage({
data: {
action: 'message'
}
});
//接收APP发送过来的消息
handleMessage(evt) {
console.log('接收到的消息:' + JSON.stringify(evt.detail.data));
}
});
</script>
</body>
</html>
uni页面:
这里为index.nvue页面(注意这个nvue,跟vue页面是有差别的,后面就是踩坑点之一)
<template>
<view class="webview-box">
<web-view ref="webview" class="webview" src="../../static/index.html" @onPostMessage="handleMessage"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
wv: null
}
},
onLoad() {
const self = this;
// #ifdef APP-PLUS
let currentWebview = getCurrentPages()[0];
setTimeout(function() {
self.wv = currentWebview.$getAppWebview();
//调用下面函数
self.handlePostMessage("消息");
}, 1000);
// #endif
},
mouted(){
},
methods: {
// 接收h5页面发来的键值判断需要执行的操作
handleMessage(evt) {
console.log("postMessage: ", evt)
},
// 获取到对应webview(关键)通过evalJs(注意大小写,如果不知道evalJ是什么,可自行百度) 执行网页的函数,可对其进行传参,完成与网页的通讯
handlePostMessage(res) {
this.$refs.webview.evalJs(`handleMessage(${res})`);
}
}
}
</script>
<style>
.webview-box {
position: absolute;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
}
.webview {
flex: 1;
}
</style>
好了,是不是觉得很简单,事实上也很简单,但是鄙人非出脑瘫,踩了两个巨坑。两个都是在uni的页面的,如果大伙也踩到的话,那恭喜了,看到了我。
第一,我用的是nvue页面,nvue获取webview窗口的方式是与普通vue获取webview的方式不一样的,这一步非常关键,如果获取不正确就算你以下写的东西是正确的也没有效果,具体是什么原理我也没深究,以后懂了再更好了,先实现业务。具体获取方法看案例,自己console一下看看要获取的是哪个webview,因为如果大伙的项目是有自定义导航栏获取其他nuve组件的话也算是一个webview。
第二个坑就是,一定要用在uni的webview组件上使用@onPostMessage
这个方法进行消息的监听,我当时也不知道犯了什么病,我用的是message,老半天调不出。message只有在特定的情况下才会接收到网页的消息,比如你执行了返回或着其他的特定场景操作的时候,具体可以看官网给出的。踩坑记录就到这啦,希望能帮助到大伙。
- 参考资料:[1] dcloud社区
18 个评论
要回复文章请先登录或注册
3***@qq.com
3***@qq.com
4***@qq.com
5***@qq.com
阿宁啊 (作者)
6***@qq.com
阿宁啊 (作者)
陌上华年