本文旨在解决vue3版本下uniapp h5项目向app项目中webview通讯问题
问题产生于uniapp不支持vue3使用template.h5.html 自定义打包模板
h5向app发送信息
有很多文章指出h5项目使用uni.postmessage 这个api需要在template.h5.html引入一个js文件 然后改下webuni变量再从manifest.json配置下改文件 就可以全文使用了
vue2环境是可以参考的
文章指向通信跳转文章
但这方案在vue3环境下是无法使用的
vue3的解决方案是直接在需要使用的页面import引入该文件
直接调用webUni.postMessage即可
<script lang="ts" setup>
import { MessageUtil } from "@/utils/MessageUtil";
import webUni from '@/static/js/uni.webview.js'
const saveImage = ()=>{
webUni.postMessage({ data: { action: 'download', data: 'http://mj-1302596703.cos.ap-guangzhou.myqcloud.com/file/ttc7sKc4g0mcSL2KbtJg.png' } });
}
</script>
接下来的问题就细化成将js文件改造成可支持model暴露了
const webUni = (function() {
"use strict";
try {
var e = {};
Object.defineProperty(e, "passive", {
get: function() {
return true;
}
}), window.addEventListener("test-passive", null, e)
} catch (e) {}
var n = Object.prototype.hasOwnProperty;
function t(e, t) {
return n.call(e, t);
}
var i = [],
a = function(e, n) {
var t = {
options: {
timestamp: +new Date
},
name: e,
arg: n
};
if (window.__dcloud_weex_postMessage || window.__dcloud_weex_) {
if ("postMessage" === e) {
var a = {
data: [n]
};
return window.__dcloud_weex_postMessage ? window.__dcloud_weex_postMessage(a) : window.__dcloud_weex_.postMessage(JSON.stringify(a));
}
var o = {
type: "WEB_INVOKE_APPSERVICE",
args: {
data: t,
webviewIds: i
}
};
window.__dcloud_weex_postMessage ? window.__dcloud_weex_postMessageToService(o) : window.__dcloud_weex_.postMessageToService(JSON.stringify(o));
}
if (!window.plus) return window.parent.postMessage({
type: "WEB_INVOKE_APPSERVICE",
data: t,
pageId: ""
}, "*");
if (0 === i.length) {
var r = plus.webview.currentWebview();
if (!r) throw new Error("plus.webview.currentWebview() is undefined");
var d = r.parent(),
s = "";
s = d ? d.id : r.id, i.push(s);
}
if (plus.webview.getWebviewById("__uniapp__service")) plus.webview.postMessageToUniNView({
type: "WEB_INVOKE_APPSERVICE",
args: {
data: t,
webviewIds: i
}
}, "__uniapp__service");
else {
var w = JSON.stringify(t);
plus.webview.getLaunchWebview().evalJS('UniPlusBridge.subscribeHandler("'.concat("WEB_INVOKE_APPSERVICE", '",').concat(w, ",").concat(JSON.stringify(i), ");"));
}
},
o = {
navigateTo: function(e) {
var n = e.url;
a("navigateTo", {
url: encodeURI(n)
});
},
navigateBack: function(e) {
var n = e.delta;
a("navigateBack", {
delta: parseInt(n) || 1
});
},
switchTab: function(e) {
var n = e.url;
a("switchTab", {
url: encodeURI(n)
});
},
reLaunch: function(e) {
var n = e.url;
a("reLaunch", {
url: encodeURI(n)
});
},
redirectTo: function(e) {
var n = e.url;
a("redirectTo", {
url: encodeURI(n)
});
},
getEnv: function(callback) {
window.plus ? callback({
plus: true
}) : callback({
h5: true
});
},
postMessage: function(e) {
a("postMessage", e.data || {});
}
};
return o;
})();
export default webUni;
直接将其替换官方提供的文件代码就能使用了
app接收
<web-view :webview-styles="webviewStyles" :src="url" @message="handlePostMessage"></web-view>
handlePostMessage(evt) {
let data = evt.detail.data[0];
const action = data?.action;
switch (action) {
case 'download': {
saveFileToPhotosAlbum(data.data)
break;
}
}
},