在uniapp开发中,有时候我们需要在vue页面中嵌入一个webview组件,用来加载一些本地或远程的网页。但是,如何在vue页面和webview之间实现数据的传递和通信呢?常用的方法是使用uniapp官方提供的组件webview ,使用uni-app提供的UniAppJSBridgeReady事件和postMessage方法,来实现vue页面和webview之间的双向数据交换。但是这种方法有一定的局限性,webview组件设置的宽高等样式只有h5有效,在app中显示只能全屏加载,无法在app中实现vue页面和webview同屏交互,本文将介绍另一种自建webview的方法,可以在app中自定义webview的宽高及显隐。
首先,我们需要在vue页面中自建一个webview组件,代码如下,下面的代码自建了webview,并且完成了vue页面对html页面数据的接收和发送:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| <template> </template> <script> export default { data() { return { topHeight: 0, windowHeight: 0, url: "/hybrid/html/test.html", fun: null, } }, methods: { init() { var _this = this; uni.getSystemInfo({ success: function(res) { _this.topHeight = res.statusBarHeight _this.windowHeight = res.windowHeight } }) var currentWebview = this.$parent.$scope.$getAppWebview(); var height = this.windowHeight - this.topHeight; wv = plus.webview.create(this.url, "webview", { top: this.topHeight + 20, scalable: true, width: '100%', height: height - 202
}) currentWebview.append(wv); let that = this this.fun = function(msg) { if (msg.data.args.data.name == 'postMessage') { let msgData = msg.data.args.data.arg console.log('app接收到消息为:' + JSON.stringify(msgData)); } } plus.globalEvent.addEventListener('plusMessage', this.fun); }, close() { if (wv) { plus.webview.close(wv); wv = null } }, evalJs(msg = "来自vue页面的参数") { let str = `getData(${JSON.stringify(msg)})` if (wv) { wv.evalJS(str); } } } } </script> <style> </style>
|
接下来,我们需要在html页面中监听UniAppJSBridgeReady事件,这个事件会在webview加载完成后触发。在这个事件的回调函数中,我们可以获取到webview的对象,然后调用它的postMessage方法,向网页发送数据。这里我们假设要发送的数据是一个字符串”Hello, webview!”。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| <!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>map</title> <style type="text/css"> html, body { height: 100%; margin: 0; overflow: hidden; } </style> <script src="./js/uni.webview.1.5.4.js"></script>
</head> <body> <button id="postData">给app的页面发送数据</button> </body> <script> document.addEventListener('UniAppJSBridgeReady', function() { let message = { action: 'hello world' } uni.postMessage({ data: message }); }); let btn = document.getElementById("postData") btn.addEventListener("click", (e) => { uni.postMessage({ data: { action: "Hello, webview!", }, }); }) window.getData = function(msgList) { console.log('接收vue组件传递来的数据:' + JSON.stringify(msgList)); } </script> </html>
|
总结一下,使用webview组件时,我们可以利用evalJS方法和postMessage方法,来实现vue页面和webview之间的双向数据交换。这样,我们就可以在uniapp中灵活地使用webview组件,来加载一些本地或远程的网页,并与它们进行通信,如果需要的就是全屏加载webview,那就不必使用本文的方法了,webview组件使用更方便一些,但是如果你需要更复杂的交互,还是自建webview更合理一些。