1. Gửi tin nhắn từ web-view đến App
Theo tài liệu chính thức về uni-app sử dụng web-view: web-view
Lưu ý đã đề cập đến phương thức postMessage, đây chính là cách web-view gửi tin nhắn đến App. Cách sử dụng như sau:
Lưu ý rằng H5 không hỗ trợ các phương thức của uni-app, vì vậy cần引入 thư viện hỗ trợ gọi các phương thức của uni-app trong dự án.
Trang web-view sử dụng:
uni.postMessage({
data: {
action: 'click'
}
});
Ứng dụng uni-app nhận tin nhắn:
<view>
<!-- #ifdef APP-PLUS -->
<uni-status-bar></uni-status-bar>
<!-- #endif -->
<web-view @message="nhanTinNhan" :src="duongDanWebView"></web-view>
</view>
nhanTinNhan(e) {
console.log('Tin nhắn từ webView')
const hanhDong = e.detail.data[0].action
}
Cách này chỉ áp dụng khi H5 không phải do UNI viết, nếu là UNI viết sẽ báo lỗi
uni.postMessage không phải là phương thức, lý do là do phương thức uni của webview xung đột với phương thức uni của uni-app, giải pháp là tải xuống js và đổi tên phương thức bên trong; ví dụ:
! function (e, n) {
"object" == typeof exports && "undefined" != typeof module ? module.exports = n() : "function" == typeof define && define.amd ? define(n) : (e = e || self).webUni = n()
}(this, (function () {
"use strict";
try {
var e = {};
Object.defineProperty(e, "passive", {
get: function () {
!0
}
}), 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 () {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
n = e.url;
a("navigateTo", {
url: encodeURI(n)
})
},
navigateBack: function () {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
n = e.delta;
a("navigateBack", {
delta: parseInt(n) || 1
})
},
switchTab: function () {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
n = e.url;
a("switchTab", {
url: encodeURI(n)
})
},
reLaunch: function () {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
n = e.url;
a("reLaunch", {
url: encodeURI(n)
})
},
redirectTo: function () {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
n = e.url;
a("redirectTo", {
url: encodeURI(n)
})
},
getEnv: function (e) {
window.plus ? e({
plus: !0
}) : e({
h5: !0
})
},
postMessage: function () {
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {};
a("postMessage", e.data || {})
}
},
r = /uni-app/i.test(navigator.userAgent),
d = /Html5Plus/i.test(navigator.userAgent),
s = /complete|loaded|interactive/;
var w = window.my && navigator.userAgent.indexOf("AlipayClient") > -1;
var u = window.swan && window.swan.webView && /swan/i.test(navigator.userAgent);
var c = window.qq && window.qq.miniProgram && /QQ/i.test(navigator.userAgent) && /miniProgram/i.test(navigator.userAgent);
var g = window.tt && window.tt.miniProgram && /toutiaomicroapp/i.test(navigator.userAgent);
var v = window.wx && window.wx.miniProgram && /micromessenger/i.test(navigator.userAgent) && /miniProgram/i.test(navigator.userAgent);
var p = window.qa && /quickapp/i.test(navigator.userAgent);
for (var l, _ = function () {
window.UniAppJSBridge = !0, document.dispatchEvent(new CustomEvent("UniAppJSBridgeReady", {
bubbles: !0,
cancelable: !0
}))
}, f = [function (e) {
if (r || d) return window.__dcloud_weex_postMessage || window.__dcloud_weex_ ? document.addEventListener("DOMContentLoaded", e) : window.plus && s.test(document.readyState) ? setTimeout(e, 0) : document.addEventListener("plusready", e), o
}, function (e) {
if (v) return window.WeixinJSBridge && window.WeixinJSBridge.invoke ? setTimeout(e, 0) : document.addEventListener("WeixinJSBridgeReady", e), window.wx.miniProgram
}, function (e) {
if (c) return window.QQJSBridge && window.QQJSBridge.invoke ? setTimeout(e, 0) : document.addEventListener("QQJSBridgeReady", e), window.qq.miniProgram
}, function (e) {
if (w) {
document.addEventListener("DOMContentLoaded", e);
var n = window.my;
return {
navigateTo: n.navigateTo,
navigateBack: n.navigateBack,
switchTab: n.switchTab,
reLaunch: n.reLaunch,
redirectTo: n.redirectTo,
postMessage: n.postMessage,
getEnv: n.getEnv
}
}
}, function (e) {
if (u) return document.addEventListener("DOMContentLoaded", e), window.swan.webView
}, function (e) {
if (g) return document.addEventListener("DOMContentLoaded", e), window.tt.miniProgram
}, function (e) {
if (p) {
window.QaJSBridge && window.QaJSBridge.invoke ? setTimeout(e, 0) : document.addEventListener("QaJSBridgeReady", e);
var n = window.qa;
return {
navigateTo: n.navigateTo,
navigateBack: n.navigateBack,
switchTab: n.switchTab,
reLaunch: n.reLaunch,
redirectTo: n.redirectTo,
postMessage: n.postMessage,
getEnv: n.getEnv
}
}
}, function (e) {
return document.addEventListener("DOMContentLoaded", e), o
}], m = 0; m < f.length && !(l = f[m](_)); m++);
l || (l = {});
var E = "undefined" != typeof webUni ? webUni : {};
if (!E.navigateTo)
for (var b in l) t(l, b) && (E[b] = l[b]);
return E.webView = l, E
}));
Ở đây đã đổi tên phương thức Uni thành webUni
Gọi phương thức:
webUni.postMessage({
data: {
chuoiNgauNhien: res.chuoiNgauNhien,
veVe: res.veVe
}
});
<strong>Còn một vấn đề, phương thức @message, nếu có tương tác dữ liệu, sau khi đóng webview rồi, vào lại trước đó dữ liệu vẫn còn tồn tại<br></br>Vì vậy cần phải hủy bỏ phương thức @message khi rời khỏi trang hoặc tại thời điểm cụ thể</strong><br></br>Ví dụ khi đóng webview
// Xóa bỏ lắng nghe khi rời khỏi trang
anTrang() {
uni.removeEventListener('message', this.xuLyTinNhan);
// this.lamNgheTinNhan = false;
},