当前位置: 首页 > news >正文

uni-app中web-view的使用

1. uni-app中web-view的使用

  uni-app中的web-view是一个 web 浏览器组件,可以用来承载网页的容器,uni-app开发的app与web-view实现交互的方式相关简单,应用通过属性@message绑定触发事件,然后在web-view的网页向应用 postMessage 触发并收到消息即可,详细请参考官网:web-view | uni-app官网 (https://uniapp.dcloud.net.cn/component/web-view.html#)主要实现代码参考下图所示。

1.1. uni-app中web-view的使用

1.1.1. app页面

<template><web-view :src="url" @message="handleMessage"></web-view>
</template><script>
export default {data() {return {url: null  //要打开的外部链接};},methods: {//通过 @message 事件接收外部链接传过来的内容handleMessage(event) {if (event.detail.data[0].isClose) {uni.reLaunch({url: '/main/main'});}}}
};
</script>

1.1.2.外部链接H5

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>我是在app里打开的页面</title><script src="./jquery-3.4.1.js" type="text/javascript" charset="utf-8"></script><!-- 微信JS-SDK 兼容微信小程序 引入此文件 --><script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script><!-- uni-app SDK --><script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script></head><body><div style="width: 100%;height: 100%;position: absolute;left: 0;top: 0;right: 0;bottom: 0;"><button id="btn">按钮</button></div></body><script>document.addEventListener('UniAppJSBridgeReady', function() {console.log("加载完成,可以使用uni相关接口");});$("#btn").click(function() {uni.postMessage({data: {isClose: true}})uni.navigateBack();})</script>
</html>

1.1.3.问题

  但是,以上方法只适合于APP,在H5环境中是不支持的,官方说明如下:
在这里插入图片描述
  那么,在uni-app如何实现在H5环境中与web-view中的网页交互通讯呢,按照官方的说法,使用window.postMessage方式实现!

1.2. window.postMessage

  关于window.postMessage的通讯原理,请参考官方档window.postMessage - Web API 接口参考 | MDN(https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage)

1.2.1. 应用端代码

onLoad: function() {window.addEventListener('message', function(e) { // 监听 message 事件console.log(e.origin);console.log("从" + e.origin + "收到消息: " + e.data);});
}

1.2.2. 网页端代码(H5)

//向uniapp发送信息
function sendMsgToUniapp(value) {parent.postMessage(value, "*");
}

  说明:uni-app的web-view,在H5环境中其实就是通过iframe来实现的,因此在iframe中的页面可直接通过jquery中的parent来获取父页面对象,并通过parent.postMessage的方式传递消息。

1.3. 完整代码

在这里插入图片描述

1.3.1. pageWeb.vue(uiapp)

<template><view><web-view @message="message":src="webViewUrl"></web-view></view>
</template><script>import pageUtil from '../../../utils/pageUtil.js';export default {data() {return {webViewUrl: '/hybrid/html/html/pageUniWeb.html?data=您好',//webViewUrl: 'http://120.224.9.76:18080/app/news/html/pageUniWeb.html?data=efhejr',wv: ''}},onReady() {pageUtil.setTitleBar('业务协同')},onLoad() {var that = this;// #ifdef APP-PLUS//此对象相当于html5plus里的plus.webview.currentWebview()。// 在uni-app里vue页面直接使用plus.webview.currentWebview()无效let currentWebview = this.$scope.$getAppWebview()setTimeout(() => {this.wv = currentWebview.children()[0]}, 300)// #endiftry {//信息交互(H5浏览器使用),监听 message 事件window.addEventListener('message',function (e) {console.log("从" + e.origin, "收到消息: ", e);var resData = e.data.data.arg;if (resData.myType) {uni.showToast({icon: 'none',title: "uniap获取H5发送数据:" + JSON.stringify(resData)});}});} catch (e) {}},methods: {//信息交互(app真机使用)message(e) {var that = thisvar resData = e.detail.data;console.log("uniap获取H5发送数据:", e)uni.showToast({icon: 'none',title: "uniap获取H5发送数据:" + JSON.stringify(resData)});var myObj = {}myObj.msg="我是uniapp"//这里必须序列化!!!myObj = JSON.stringify(myObj)this.wv.evalJS(`postJS(${myObj})`);},}}
</script>
<style>
</style>

1.3.2. pageUniWeb.html(H5)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>web-view</title><script type="text/javascript" src="../static/js/init-rem.js"></script><script type="text/javascript" src="../static/js/jquery-3.1.1.min.js"></script><script type="text/javascript" src="../static/helper/init-helper.js"></script><!--    <script src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"--><!--            type="text/javascript" charset="utf-8"></script>--><script type="text/javascript" src="../static/helper/web-view-custom.js"></script><script type="text/javascript" src="../static/js/vconsole.min.js"></script><script type="text/javascript">var vc = new VConsole()</script><style>.btn-layout {display: flex;flex-direction: column;align-items: center;}.btn-item {display: inline;font-size: 0.32rem;color: white;text-align: center;padding: 0.2rem 0.5rem;border-radius: 0.3rem;margin-top: 0.5rem;background-color: #1AAD19;}.content {display: inline;font-size: 0.32rem;color: black;text-align: center;padding: 0.2rem 0.5rem;border-radius: 0.3rem;margin-top: 0.5rem;}</style>
</head>
<body>
<div class="btn-layout"><span id="h5ToUniappId" class="btn-item">H5发送数据到uniapp</span><div id="contentId" class="content"></div><div id="content2Id" class="content"></div>
</div></body>
<script type="text/javascript">var itemData = getParamByKey('data');console.log("获取uniapp链接传递数据:", itemData)$(function () {$('#contentId').html("获取uniapp链接传递数据:"+itemData)});/*** 获取uniapp传递数据方法一* 定义全局方法,接收来自应用的信息*/// window.postJS = (msg) => {//     console.log('来自应用的消息', msg)// }/*** 获取uniapp传递数据方法二*/function postJS(e) {console.log("获取uniapp传递数据:", e)$('#content2Id').html("获取uniapp传递数据:"+JSON.stringify(e))}document.addEventListener('UniAppJSBridgeReady',function () {webUni.webView.getEnv(function (res) {console.log('当前环境:' + JSON.stringify(res));});document.querySelector('#h5ToUniappId').addEventListener('click', function (evt) {// webUni.webView.navigateBack();//向uniapp传值//方法一//window.parent.postMessage("", '*')//parent.postMessage("sdcec", "*");//方法二webUni.postMessage({data: {action: 'message',msg: '我是H5',myType: 'typeH5',}});});});
</script>
</html>

1.3.3. 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
}));

1.3.4. init-helper.js

var u = navigator.userAgent;
// 是否为ios设备
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
// 是否为PC端
var isPC = typeof window.orientation === 'undefined';
// 是否为android端
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;
// 是否为微信端,此处不能为===,因为match的结果可能是null或数组
var isWx = u.toLowerCase().match(/MicroMessenger/i) == 'micromessenger';
var strConstant = {/*** 业务协同*///待办eventWaitDeal: '我的待办',//已办eventHasDeal: '我的已办',//考勤打卡workCheckSign: '考勤打卡',//添加pageTypeAdd: 'add',//编辑pageTypeEdit: 'edit',/*** 跳转类型*/jumpTypeMapLoc: 'jumpTypeMapLoc',
}/*** @desc 返回上一页*/
function backPage() {//单击Android左上角返回键执行该方法history.pushState(null, null, location.href);window.addEventListener('popstate',function (event) {if (isAndroid) {if (window.androidJsHook) {history.pushState(null, null, location.href);window.androidJsHook.htmlFinish();} else {history.go(-1)}} else if (isiOS) {if (window.webkit) {history.pushState(null, null, location.href);window.webkit.postMessage(null);} else {history.go(-1)}} else {history.go(-1)}});
};/*** 跳换页面*/
function openPage(webUrl, webTitle, webParams) {if (window.androidJsHook) {window.androidJsHook.startForResult(webUrl, webTitle, webParams);} else {mui.openWindow({url: webUrl + webParams,id: webUrl,styles: {top: '0px',bottom: '0px'},waiting: {autoShow: false, //自动显示等待框,默认为true}});}
}/*** @description 通过传入key值,得到页面key的初始化传值* plus情况为plus.webview.currentWebview.**** h5情况为 window.location.href 中的参数的值* @param {String} key*/
function getParamByKey(key) {if (!key) {return null;}return GetQueryString(key) || getExtraDataByKey(key);
};function GetQueryString(name) {//  var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");//  var r = window.location.search.substr(1).match(reg);//  if (r != null) return unescape(r[2]); return null;/*中文不乱码*/return decodeURIComponent((new RegExp('[?|&]' + name+ '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [, ""])[1].replace(/\+/g, '%20')) || null;
}/*** @description 通过传入key值,得到页面key的初始化传值* plus情况为plus.webview.currentWebview.**** h5情况为 window.location.href 中的参数的值* @param {String} key*/
function getExtraDataByKey(key) {if (!key) {return null;}var value = null;//h5value = getUrlParamsValue(window.location.href, key);if (value === 'undefined') {value = null;}return value;
};/*** 删掉遮罩*/
function removeDrop() {$('.mui-popup-backdrop').remove();
}/*** 合并json对象* @param {Object} target 第一个json对象,同时也是合并后的json对象* @param {Object} source 第二个json对象*/
function extend(target, source) {for (var obj in source) {target[obj] = source[obj];}return target;
}/*** 转为json数据格式* @param {Object} idStr form表单的id*/
function transformToJson(idStr) {var formData = $("#" + idStr).serializeArray();var obj = {};var j = 1;for (var i in formData) {obj[formData[i].name] = formData[i]['value'];//伪数组length字段,用于遍历改造json对象obj['length'] = j;j++}return obj;
}/*** 通用方法封装处理* commonUtils.isEmpty(jsonParam.countyLabel*/
var commonUtils = {// 判断字符串是否为空isEmpty: function (value) {if (value == null || this.trim(value) == "" || value == undefined) {return true;}return false;},// 判断一个字符串是否为非空串isNotEmpty: function (value) {return !commonUtils.isEmpty(value);},// 空格截取trim: function (value) {if (value == null) {return "";}return value.toString().replace(/(^\s*)|(\s*$)|\r|\n/g, "");},// 判断字符串是否是以start开头startWith: function (value, start) {var reg = new RegExp("^" + start);return reg.test(value)}
};/*** 重置form表单*/
function resetForm(resetArr) {var textInputArr = $("input[type='text']")var numberInput = $("input[type='number']")var domId = nullfor (var i = 0; i < textInputArr.length; i++) {domId = $(textInputArr[i]).attr('id')var isContain = falseresetArr.forEach(function (item, index) {if (domId == item) {isContain = true}})if (!isContain) {$(textInputArr[i]).val("")}}for (var i = 0; i < numberInput.length; i++) {domId = $(numberInput[i]).attr('id')var isContain = falseresetArr.forEach(function (item, index) {if (domId == item) {isContain = true}})if (!isContain) {$(numberInput[i]).val("")}}
}/*** 更新三级联动字典* @param {Object} name* @param {Object} nameMS* @author zzs*/
function updateDictLevel3(name, nameMsArr, urlStr) {var queryParam = {};if (isNotNull(name)) {queryParam.name = name;}getNetData(urlStr, queryParam, function (result) {if (result.code == '200') {var nameA = [];if (result.data && result.data.length == 0) {nameA = [{"id": "","value": "请选择"}];} else {$.each(result.data, function (i, item) {var flag = {};flag.id = item.value;flag.value = item.label;//二级var childsA = [];if (item.children && item.children.length > 0) {$.each(item.children, function (j, childsItem) {var childsFlag = {};childsFlag.id = childsItem.value;childsFlag.value = childsItem.label;//三级var childsB = [];if (childsItem.children && childsItem.children.length > 0) {$.each(childsItem.children, function (k, grandsonItem) {var grandsonFlag = {};grandsonFlag.id = grandsonItem.value;grandsonFlag.value = grandsonItem.label;childsB.push(grandsonFlag);});}childsFlag.childs = childsB;childsA.push(childsFlag);});}flag.childs = childsA;nameA.push(flag);});}if (nameMsArr != null && nameMsArr.length > 0) {nameMsArr.forEach(function (nameMs, index) {nameMs.updateWheels(nameA);})}}})
}

相关文章:

  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • 数据结构:Trie(前缀树/字典树)
  • 2核4g服务器能支持多少人访问?阿里云2核4g服务器在线人数
  • 【论文精读】CAM:基于上下文增强和特征细化网络的微小目标检测
  • 基于RLS的永磁同步电机谐波抑制--FFT分析
  • C++蓝桥考级一级到十八级的考点内容整理
  • LeetCode题练习与总结:字母异位词分组
  • Java类与对象:从概念到实践的全景解析!
  • 在 Linux 中通过 SSH 执行远程命令时,无法自动加载环境变量(已解决)
  • 【Leetcode】top 100 栈
  • SpringBoot -- 整合SpringMVC
  • JavaScript如何制作轮播图
  • 程序员开发技术整理(持续整理中)
  • LeetCode 2908.元素和最小的山形三元组 I:贪心(两次遍历)——双O(n)复杂度
  • kafka部署之简单密钥
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • [译]Python中的类属性与实例属性的区别
  • Android 架构优化~MVP 架构改造
  • bootstrap创建登录注册页面
  • Effective Java 笔记(一)
  • gcc介绍及安装
  • JavaScript DOM 10 - 滚动
  • Joomla 2.x, 3.x useful code cheatsheet
  • Laravel 中的一个后期静态绑定
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • Python打包系统简单入门
  • Redux系列x:源码分析
  • 爱情 北京女病人
  • 从零开始的无人驾驶 1
  • 规范化安全开发 KOA 手脚架
  • 蓝海存储开关机注意事项总结
  • 深入 Nginx 之配置篇
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 提醒我喝水chrome插件开发指南
  • 学习HTTP相关知识笔记
  • 用Canvas画一棵二叉树
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • ​低代码平台的核心价值与优势
  • #### go map 底层结构 ####
  • #git 撤消对文件的更改
  • #控制台大学课堂点名问题_课堂随机点名
  • (10)ATF MMU转换表
  • (30)数组元素和与数字和的绝对差
  • (AngularJS)Angular 控制器之间通信初探
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (三)Hyperledger Fabric 1.1安装部署-chaincode测试
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (十五)Flask覆写wsgi_app函数实现自定义中间件
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • .Net CF下精确的计时器
  • .NET Core 版本不支持的问题
  • .net core开源商城系统源码,支持可视化布局小程序
  • .Net开发笔记(二十)创建一个需要授权的第三方组件
  • @html.ActionLink的几种参数格式
  • @RequestMapping-占位符映射