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].method
let value = e.detail.data[0].value
switch (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].method
let value = e.detail.data[0].value
switch (method) {
case 'getTitle':
this.pageTitle = value
uni.setNavigationBarTitle({
title: value
})
break;
default:
break;
}
}
H5端,在每个单页面onShow都获取网页标题,其实也可以直接把每个标题具体值直接传过去
onShow() {
var pages = getCurrentPages()
var page = pages[pages.length - 1]
var title = page.$holder.navigationBarTitleText
uni.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
},