APP端:
<web-view :webview-styles="webviewStyles" :src="src" @message="handleByH5"></web-view>
data() {
return {
wv: null,
src: '',
webviewStyles: {
progress: {
color: '#43ACFF'
}
},
isCanBack: true, // 是否允许手机物理返回
}
}
引用
app给H5传参:通过h5地址传参
这个方法简单,就是直接通过src 地址后面通过? &
拼接参数
- app端
onLoad() {
this.src = 'https://editor.csdn.net/md?articleId=130581348'
}
- h5端通过uniapp生命周期函数
onLoad
接收参数
onLoad({ articleId }) {
// .....
}
app给H5传参:通过方法evalJS
传参
H5给app传参:通过web-view
组件的@message
绑定的方法
处理H5页面的手机物理返回问题
这里将
app给H5传参:通过方法evalJS传参
和H5给app传参:通过web-view 组件的@message绑定的方法
、处理H5页面的手机物理返回问题
写一起了,方便查看app和H5之间的通信交互。
详见代码
- app端
onBackPress(options) {
// 这里return true禁用手机的物理返回,避免H5页面使用返回的时候也调用app的手机物理返回
// return false 允许手机的物理返回
if (options.from == 'backbutton') {
return this.isCanBack
}
},
onLoad() {
// #ifdef APP-PLUS
this.$showLoading('正在努力加载中,请稍候……')
let currentWebview = this.$scope.$getAppWebview() //此对象相当于html5plus里的plus.webview.currentWebview()。在uni-app里vue页面直接使用plus.webview.currentWebview()无效
setTimeout(() => {
let wv = currentWebview.children()[0]
this.wv = wv
this.wv.setStyle({
bottom: 0
})
// 处理web-view h5页面的手机物理返回问题
plus.key.addEventListener('backbutton', () => {
// 监听返回事件
wv.canBack((e) => {
if (e.canBack) {
this.isCanBack = true
wv.back() // 返回上一页
} else {
// wv.close(); // 关闭嵌入的H5应用
this.isCanBack = false
}
})
})
this.$hideLoading()
}, 1000) // 注意这里跳转过去的都是相当于是一级页面,所以需要延迟一下,如果报xxx is not undefined,则是因为对应的页面还没有加载出来,相应的xxx 方法就没有挂载上去
// #endif
},
methods: {
// 监听 H5 发送过来的消息,也就是webView.postMessage过来的信息
handleByH5(data) {
console.log('监听H5的操作 ----index------ data', data)
const { pageBack } = data.detail.data[0]
switch (action) {
case 'pageBack':
pageBack()
break
case 'getLocation':
// 获取位置
this.getCurrentLocation()
break
}
},
// 获取当前位置信息
async getCurrentLocation() {
const res = await getLocation()
console.log('获取当前位置信息----', res)
if (res && !res.errMsg) {
const { longitude, latitude, address } = res
let locationInfo = {
longitude,
latitude,
location: address.poiName
}
// 将结果返回给H5页面,evalJS触发H5中绑定在window上的方法getLocationByApp,达到传参的目的
this.wv.evalJS(`getLocationByApp('${JSON.stringify(locationInfo)}')`)
} else {
// 将结果返回给H5页面
this.wv.evalJS(`getLocationByApp('${JSON.stringify(false)}')`)
}
},
}
引用
- App端web-view的扩展:上述出现的相关api官网都有说明
- evalJS:在Webview窗口中执行JS脚本
- h5端
定义一个webviewUtil.js
文件,将所有的与app通信的方法都放在里面,方便维护
webviewUtil.js
import $this from '@/main'
// $this vue实例,在main.js中已经将vue实例抛出
/**
* 调用app的获取定位信息
*/
export const getLocationByApp = (callback) => {
// 这一步是向APP传参,APP中通过web-view的@message绑定的handleByH5方法接收对应的参数
$this.$myUni.webView.postMessage({
data: {
action: "getLocation",
},
});
window.getLocationByApp = (res) => {
let result = JSON.parse(res);
callback && callback(result)
}
setTimeout(() => {
let defaultLocationInfo = {
longitude: 115.995196,
latitude: 28.675518,
location: '南昌市'
}
callback && callback(defaultLocationInfo)
}, 1000)
}
main.js
import Vue from 'vue'
import App from './App'
// 需要使用到uni.webview.js的一些方法
import * as uniWebView from '@/common/uni_webview.js'
document.addEventListener('UniAppJSBridgeReady', () => {
// 将uniWebView赋值给vue原型,方便调用
Vue.prototype.$myUni = uniWebView
});
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
// 将vue 实例抛出,方便某些js文件中调用vue api
export default app;
需要下载 uni-webview.js,来调用webview的一些方法
最后,就是在相应的页面中调用webviewUtil.js
封装的方法
export const getCurrLocation = () => {
return new Promise((resolve) => {
getLocationByApp((locationInfo) => {
if (!locationInfo) {
let defaultLocationInfo = {
longitude: 115.995196,
latitude: 28.675518,
location: '南昌市'
}
resolve(defaultLocationInfo)
return
}
resolve(locationInfo)
})
})
}
总结:
- app给h5通信
- 可以通过
webview
组件绑定的src
地址拼接参数传参; - 也可以通过
evalJS
方法调用H5端window.xxx
绑定的方法,通过方法传参;
- 可以通过
- h5给app传参
- 通过下载的
uni.webview.js
文件调用webView.postMessage
传参,APP
通过web-view
组件的@message
绑定的方法接收参数
- 通过下载的