目前遇到个需求:用uniapp开发app和H5,另外起一个项目打包成模版单页(减少app更新),在应用内用webview嵌入模版单页
1、先在单页项目中引入web-view-custom.js
之前发现在网上说是直接引入<script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.1.js"></script>
但是调用uni.postMessage()会报错- 查找原因如下
- 使用uniapp项目写H5 webview,使用hello uniapp的模板,按照webview文档里的源码往template.h5.html里面写入相关内容。
- 引入的https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js脚本,它这个地方是个坑。你要手动改源码。uni.webview.js文件里面注册的就是uni对象。被uniapp项目自带的uni对象覆盖了,我就是把源码里面注册uni对象换了个名字(webUni)就好了。
- 下边会提供自定义的web-view-custom.js,可以直接使用webUni.postMessage方法。
2、App项目与webview
1. 利用原生直接创建webview
APP
template
<view class="webview">
<!-- #ifdef H5 -->
<web-view :src="url" @message="message" class="addddddddddddd" :webview-styles="{'padding-top':'44px'}"></web-view>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<!-- <web-view :src="url" @message="getMessage" class="app" :webview-styles="{'padding-top':'44px'}"></web-view> -->
<!-- #endif -->
</view>
script
// #ifdef APP-PLUS
var that = this;
that.statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
var link = this.url;
var w = plus.webview.create(
link,
'batch_view',
{
top: uni.getSystemInfoSync().statusBarHeight + 44,//放置在titleNView下方。如果还想在webview上方加个地址栏的什么的,可以继续降低TOP值
//因为设置top之后 webview的高度依然不变会往下移 底部会被遮住 所以设置一下高度
height: uni.getSystemInfoSync().windowHeight - 44 - uni.getSystemInfoSync().statusBarHeight,
},//不用data
{
preload: 'preload webview'
},
); // 可直接通过以下方法获取preload值
var currentWebview = this.$mp.page.$getAppWebview() //获取当前页面的webview对象
currentWebview.append(w); //一定要append到当前的页面里!!!才能跟随当前页面一起做动画,一起关闭
// 监听webview里边的页面的postMessage
plus.globalEvent.addEventListener('plusMessage', function(msg) {
console.log('//web传来的参数',msg.data.args.data)//web传来的参数
let teamShare = msg.data.args.data
if ((JSON.stringify(teamShare) !== "{}")) {
that.title = teamShare.arg.teamShare.title
that.description = teamShare.arg.teamShare.description
that.image = teamShare.arg.teamShare.image
that.teamCode = teamShare.arg.teamShare.teamCode
console.log('最终//web传来的参数',that.title,that.description,that.teamCode)//web传来的参数
}
})
// #endif
webview中的里边的页面
// 这是webview中一个点击按钮,触发以下代码即可
webUni.postMessage({
data: {
teamShare:{
title:title,
description:description,
image:image,
teamCode:teamCode
}
}
})
3、直接用webview组件
App
template
<view class="webview">
<!-- #ifdef H5 -->
<web-view :src="url" @message="message" class="addddddddddddd" :webview-styles="{'padding-top':'44px'}"></web-view>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<web-view :src="url" @message="getMessage" class="app" :webview-styles="{'padding-top':'44px'}"></web-view>
<!-- #endif -->
</view>
script
getMessage(msg){
console.log('webview传来的消息',msg)
},
注意:message一般放在以下情况中,放在method会出现一些问题
,分享初始化一般直接放在onLoad
webview中的里边的页面
// 这是webview中一个点击按钮,触发以下代码即可
webUni.postMessage({
data: {
teamShare:{
title:title,
description:description,
image:image,
teamCode:teamCode
}
}
})
3、H5项目与webview
H5项目
template
<view class="webview">
<!-- #ifdef H5 -->
<web-view :src="url" @message="message" class="addddddddddddd" :webview-styles="{'padding-top':'44px'}"></web-view>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<!-- <web-view :src="url" @message="getMessage" class="app" :webview-styles="{'padding-top':'44px'}"></web-view> -->
<!-- #endif -->
</view>
script
// #ifdef H5
let that = this
window.addEventListener('message', (msg) => {
console.log('H5与webview之间的通信2', msg.data.data)
let teamShare = msg.data.data
if ((JSON.stringify(teamShare) !== "{}")) {
that.title =teamShare.arg ? teamShare.arg.teamShare.title:that.title
that.description = teamShare.arg ? teamShare.arg.teamShare.description:that.description
that.image = teamShare.arg ? teamShare.arg.teamShare.image:that.image
console.log('最终//web传来的参数',that.title,that.description,that.teamCode)//web传来的参数
}
})
let H5shareUrl = this.teamCode ? `${window.location.href}&teamCode=${this.teamCode}` : `${window.location.href}`
this.initShare({
title: `赶快来参与${this.title}`, // 分享标题
desc: this.description, // 分享描述
//#ifdef H5
link: H5shareUrl, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
//#endif
imgUrl: this.image, // 分享图标
inviteCode:this.code
})
// #endif
webview中的里边的页面
// 这是webview中一个点击按钮,触发以下代码即可
webUni.postMessage({
data: {
teamShare:{
title:title,
description:description,
image:image,
teamCode:teamCode
}
}
})
4、web-view-custom.js
! 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
}));