前言
web-view是uni-app的一个内置组件,可以在应用里打开指定的网页,应用和网页之间可以收发消息。
官方文档地址:官网>文档>组件>内置组件>web-view
1.调用uni.postmessage被告知方法不存在(uni.postmessage is not a function)
官方文档web-view有几个相关方法,**uni.postmessage(object)**的描述是:网页向应用发送消息:

web-view是uniapp内置组件,并有自带的方法可以支持消息传递,考虑到uniapp本身可以发布成h5网页,所以就直接创建了一个新的uniapp项目,用来做跳转目标网页。
直接在新项目index页面测试:
<template>
<button type="button" @click="sendmess">发送</button>
</template>
<script setup>
const sendmess = (e) => {
uni.postmessage({
data: {
action: 'message'
}
});
}
</script>
<style lang="scss" scoped>
</style>
然后在应用里添加web-view,指向目标网页:
<web-view src="目标网页" @message="消息接收方法"></web-view>
在手机上测试可以正常打开网页,但是点击按钮,调用uni.postmessage方法时报错:
typeerror: uni.postmessage is not a function
这里先试用了uniapp其他几个常用的内置api,比如uni.showtoast(object),来证明内置的方法有正常加载,点击按钮,结果正常运行:
uni.showtoast({
title: '标题',
duration: 2000
});
重新阅读文档,发现在web-view加载html网页的示例中,引入了一个uni.webview.js文件,因为这个示例是个传统的html页面,之前以为用的是内置方法就忽略了:

把文件下载下来,下载地址文档上有提供,当前最新是1.5.6:
https://gitcode.net/dcloud/uni-app/-/raw/dev/dist/uni.webview.1.5.6.js在网页项目的main.js文件中对文件进行引用:
import '/static/js/uni.webview.1.5.6.js'
重新点击按钮,问题仍然存在,但是把uni对象打印出来,前后对比发现多了一个webview,展开就看到了相关方法:

所以发送方法改成:
<script setup>
const sendmess = (e) => {
uni.webview.postmessage({
data: {
action: 'message'
}
});
}
</script>
消息正常发送并接收。
2.h5无法接收消息
上边用手机测试通过,但在浏览器中进行访问,就接收不到消息:
官方文档中有标示:

根据文档需要用window.postmessage,这个方法之前使用,是在web网页中嵌套iframe,父子页面通信的时候,文档上可以看到组件会被转成iframe:

注意:这里只要修改应用这边(变成浏览器访问之后就是父级页面这里),需要以window.addeventlistener监听消息,网页端也就是子级不需要修改。
<template>
<view>
<web-view src="目标网页" @message="listenmess"></web-view>
</view>
</template>
<script setup>
import {
onbeforeunmount
} from "vue";
import {
onload
} from "@dcloudio/uni-app";
const listenmess = (e) => {
console.info(e);
}
onload(() => {
// #ifdef h5
window.addeventlistener('message', listenmess, false);
// #endif
});
onbeforeunmount(() => {
// #ifdef h5
window.removeeventlistener("message", listenmess);
// #endif
});
</script>
<style lang="scss" scoped>
</style>
使用方法window.addeventlistener监听消息,添加window.removeeventlistener防止监听重复执行,需要注明只在h5情况下执行,否则手机应用会报错:
typeerror: cannot read property 'addeventlistener' of undefined
3.根据官方文档中的示例编写html页面
官方文档示例是一个传统的html页面,写个简单的页面用nginx发布出来(web-view仅支持加载网络网页,不支持本地html),作为目标网页试一下:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>测试</title>
</head>
<body>
<button id="sendmess">发送</button>
<script type="text/javascript" src="/uni.webview.1.5.6.js"></script>
<script type="text/javascript">
document.getelementbyid('sendmess').addeventlistener('click', function() {
uni.postmessage({
data: {
action: 'message'
}
});
});
</script>
</body>
</html>
注意:这里是uni.postmessage,和uniapp项目中调用不同。
经测试消息可以成功传递。
然后文档上还写到uniapp项目里也能加载html网页,只要把文件放在/hybrid/html中:

写个html放进去,uni.webview.1.5.6.js放到js路径里:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>测试</title>
</head>
<body>
<button onclick="sendmess()">发送</button>
<script src="/hybrid/html/js/uni.webview.1.5.6.js"></script>
<script type="text/javascript">
function sendmess() {
uni.postmessage({
data: {
action: 'message'
}
});
}
</script>
</body>
</html>
经测试消息可以成功传递。
4.vue项目作为网页端调用uni.postmessage方法
因为之前有个vue2的项目里有相应功能网页,就拿来用做目标,然后在依赖库里搜到了@dcloudio/uni-webview-js,就没用上边的js,直接安装引入之后,实测可以正常使用:
<template>
<el-button type="primary" @click="sendmess">发送</el-button>
</template>
<script>
import uniwebview from '@dcloudio/uni-webview-js'
export default {
components: {
uniwebview
},
methods: {
sendmess() {
uniwebview.postmessage({
data: { action: 'message' }
});
}
}
}
</script>
<style></style>总结
到此这篇关于如何使用uniapp内置组件webview消息传递的文章就介绍到这了,更多相关uniapp内置组件webview消息传递内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论