1.app端实现
注意:为了实现实时通信,app端页面是.nvue
代码实现
<template><view class="content"><view class="web-view"><web-view class="web-view" :src="url" ref="webview" @onPostMessage="onPostMessage"></web-view></view></view>
</template><script>export default {data() {return {url: '',}},methods: {onPostMessage(e) {let method = e.detail.data[0].methodlet value = e.detail.data[0].valueswitch (method) {case 'test':console.log("test")break;case 'back':uni.switchTab({url: '/pages/home/index'})break;case 'copy':uni.setClipboardData({data: value,showToast: false,success: function() {uni.showToast({title: 'copy',duration: 2000});}})break;default:break;}}}}
</script><style scoped lang="scss">.content {width: 750rpx;flex: 1;background-color: #f7f7f7f7;display: flex;align-items: center;height: 100vh;.web-view {height: 100%;width: 750rpx;flex: 1;}}
</style>
2.H5端实现(基于uniapp的H5)
2.1 manifest.json配置
将模板路径指向项目中的index.html
2.2 模板index.html配置
注意:uni.webview.1.5.2.js 文件路径,放在static文件下
资源文件放在:https://www.alipan.com/s/3DaYWBod57B
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title><%= htmlWebpackPlugin.options.title %></title><script>var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||CSS.supports('top: constant(a)'))document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +(coverSupport ? ', viewport-fit=cover' : '') + '" />')</script><link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" /></head><body><div id="app"></div></body><script type="text/javascript" src="./static/js/uni.webview.1.5.2.js"></script><script>document.addEventListener('UniAppJSBridgeReady', function() {uni.webView.getEnv(function(res) {console.log('当前环境:' + JSON.stringify(res));});});</script>
</html>
2.3 H5代码实现,调用app端方法
注意:调用uni.postMessage 一定要加上webView
uni.webView.postMessage({data: {method: 'getTitle',value: title}});
现在就可以实现在H5端调用app端的方法
3.遇见的问题及解决方案
3.1 H5有多个页面,app端使用.nvue无法显示网页标题
解决方案,增加通信,每一个新页面H5将网页标题传递给app端,然后app端手动更改标题(暂时想到的笨办法,有其他解决方案的欢迎交流)
app端实现代码
onPostMessage(e) {let method = e.detail.data[0].methodlet value = e.detail.data[0].valueswitch (method) {case 'getTitle':this.pageTitle = valueuni.setNavigationBarTitle({title: value})break;default:break;}}
H5端,在每个单页面onShow都获取网页标题,其实也可以直接把每个标题具体值直接传过去
onShow() {var pages = getCurrentPages()var page = pages[pages.length - 1]var title = page.$holder.navigationBarTitleTextuni.webView.postMessage({data: {method: 'getTitle',value: title}});}
3.2 H5跳转到二级页面,app端点击一下就退出webView页面了
解决方案,app端退出拦截,根据网页标题来判断是否退出当前页面,否则就控制webView页面后退
onBackPress(event) {if (this.pageTitle == 'Invitar amigos') {uni.switchTab({url: '/pages/home/index'})} else {this.$refs.webview.evalJs("javascript:history.back(-1)");}return true},