uniapp 之 uniapp app 与uniapp H5的通信 webview,以及处理H5页面的手机物理返回问题

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)}')`)
		}
	},
}

引用

  • h5端
    定义一个webviewUtil.js文件,将所有的与app通信的方法都放在里面,方便维护
    在这里插入图片描述

webviewUtil.js

扫描二维码关注公众号,回复: 16732666 查看本文章
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绑定的方法接收参数

猜你喜欢

转载自blog.csdn.net/Zhuangvi/article/details/130581348