因为公司开发的公司内部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 = false
const 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,
});
},
});