因为公司开发的公司内部APP功能没有太多涉及到原生方法,加上功能迭代太快,如果一直更新APP导致体验不好,所以决定所有页面都用webview来做,APP就一个壳子,里面所有页面都在外面,这里就有一个APP和webview通讯的问题,网上找了一些解决方案,试了很多方法
APP端
<template><web-view :src="url" ref="webview" @message="message"></web-view>
</template><script>let currentWebview;export default {data() {return {url: ''};},onLoad(e) {this.url = 'webview路径'this.$nextTick(() => {currentWebview = this.$scope.$getAppWebview()})},methods: {message(e) {//webview发送给app的消息let apis = JSON.parse(e.detail.data[0])uni[apis.apiKey]({...apis.data,success: (e) => {if (apis.isSuccessFn) {setTimeout(function() {let wv = currentWebview.children()[0]wv.evalJS(`apiSuccess(${JSON.stringify(e)})`)}, 0);}},fail: (e) => {if (apis.isFailFn) {setTimeout(function() {let wv = currentWebview.children()[0]wv.evalJS(`apiFail(${JSON.stringify(e)})`)}, 0);}}})}}}
</script>
webview里面的,这里的h5也是
uniapp
,如果是其他的也可以修改
main.js
//首先引入uniapp的配置文件,官网自己找下载连接
import App from './App'
import '@/static/js/uni.webview.1.5.4'
import Vue from 'vue'
document.addEventListener('UniAppJSBridgeReady', function() {Vue.config.productionTip = falseconst app = new Vue({...App})app.$mount()
});
封装的js
export function uniApi(apiKey, data = {}) {if (data.success) {window.apiSuccess = data.success}if (data.fail) {window.apiFail = data.fail}uni.webView.getEnv(async (res) => {if (res.plus) {//APP里面的webview环境uni.webView.postMessage({data: JSON.stringify({apiKey: apiKey,data: data,isSuccessFn: data.success ? true : false,isFailFn: data.fail ? true : false,})})}else{try {uni[apiKey](data)} catch (e) {console.log(e)}}})if (env === 'plus') {} else {try {uni[apiKey](data)} catch (e) {console.log(apiKey)console.log(e)}}
}
页面需要调用APP原生方法,比如调用一个扫码功能,h5是不具备扫码功能
uniApi('scanCode',{onlyFromCamera: true, // 只允许从相机扫码success(res) {console.log("扫码成功:"+JSON.stringify(res))// 扫码成功后 在此处理接下来的逻辑},fail(err) {uni.showToast({title: "扫描失败",icon: "none",duration: 1000,});},
});