uni-app实现web-view和App之间的相互通信

news2024/11/25 2:35:21

双向实时

如果app端部署成网站,则web-view就是iframe,使用也可以双向通讯

https://uniapp.dcloud.net.cn/component/web-view.html

APP端代码

index.vue:

<template>
  <web-view
    id="m-webview"
    :fullscreen="true"
    :src="webViewSrc"
    :webview-styles="{ height: '400px' }"
    @message="handleMessage"
    @onPostMessage="handlePostMessge"
    @load="handleLoad"
    @error="handleError"
  ></web-view>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'

let webViewSrc = ref('')
let webview: any
//#region 事件
const handleH5Message = (value: any) => {
  console.log('父应用接收消息,handleH5Message', value.data.data)
  handleH5PostMessage()
}

const handleMessage = (value: any) => {
  console.log('父应用接收消息,handleMessage', value)
  webview.evalJS('globalCallbackForApp("点击")')

  if (Array.isArray(value.detail?.data) && value.detail.data.length > 0) {
    if (
      value.detail.data[0].type === 'msg' &&
      value.detail.data[0].value === 'chooseImage'
    ) {
      if (value.detail.data[0].callback) {
        webview.evalJS(`${value.detail.data[0].callback}("自定义点击")`)
      }

      uni.chooseImage({
        count: 1, // 默认9, 设置图片的选择数量
        sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
        sourceType: ['album'], // 从相册选择
        success: (res) => {
          // 返回选定照片的本地文件路径列表 tempFilePaths
          console.log(res.tempFilePaths)
        },
        fail: (err) => {
          // 处理错误
          console.error(err)
        },
      })
    }
  }
}

const handlePostMessge = (value: any) => {
  console.log('handlePostMessge', value)
}

const handleLoad = (value: any) => {
  console.log('handleLoad', value)
}

const handleError = (value: any) => {
  console.log('handleError', value)
}

//#endregion

const handleMessageInit = () => {
  // #ifdef H5
  window.removeEventListener('message', handleH5Message)
  window.addEventListener('message', handleH5Message)
  // #endif
}

const handleH5PostMessage = () => {
  var iframe: any = document.getElementById('m-webview')
  var message = {
    target: 'iframe',
    data: 'Hello, I am your parent',
  }
  console.log('父应用发送消息', message)

  iframe.contentWindow.postMessage(message, '*')
}

const init = (option: any) => {
  handleMessageInit()
  webViewSrc.value = option.webViewUrl

  // #ifdef APP-PLUS
  //https://uniapp.dcloud.net.cn/tutorial/page.html#getappwebview
  let pages = getCurrentPages()
  let page: any = pages[pages.length - 1]
  let currentWebview = page.$getAppWebview()

  setTimeout(() => {
    webview = currentWebview.children()[0]

    console.log('this.wvNode.evalJS2', typeof webview.evalJS)
    if (typeof webview.evalJS === 'function') {
      console.log('执行')
      webview.evalJS('globalCallbackForApp("初始化")')
    }
  }, 1000)

  // #endif
}

onLoad((option) => {
  init(option)
})
</script>

<style lang="scss" scoped></style>

被嵌入的网页端代码

list-user.vue:

<template>
	<view>
		<view class="m-title">工艺报警</view>
		<text>{{ title }}</text>
		<view class="m-btn-wrap">
			<cl-button @click="handleClick">打开相册</cl-button>
		</view>
	</view>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";

const title = ref("");

//#region 事件
const handleFormatPostMessageData = (value: any) => {
	if (typeof value.callbackFun === "function") {
		window[value.callback] = value.callbackFun;
		delete value.callbackFun
	}
	return {
		...value,
	};
};

const handleClick = () => {
	console.log("子应用发送消息");

	webViewUni.postMessage({
		data: handleFormatPostMessageData({
			type: "msg",
			value: "chooseImage",
			callback: "customCallbackClick",
			callbackFun: (data: any) => {
				console.log("子应用接收父应用的实时消息【自定义】:", data);
			},
		}),
	});
};

//#endregion

const init = () => {
	window.addEventListener(
		"message",
		function (event) {
			if (event.data.target === "iframe") {
				console.log("子应用接收消息:", event.data.data);
			}
		},
		false,
	);
};

onLoad(() => {
	init();
});
</script>

<style lang="scss" scoped>
.m-title {
	padding: 20rpx;
	color: #666;
	font-size: 40rpx;
}
.m-btn-wrap {
	padding: 20rpx;
}
</style>

hybrid_html_uni.webview.1.5.5.js:

!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e=e||self).uni=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 i(e,i){return n.call(e,i)}var t=[];function o(){return window.__dcloud_weex_postMessage||window.__dcloud_weex_}function a(){return window.__uniapp_x_postMessage||window.__uniapp_x_}var r=function(e,n){var i={options:{timestamp:+new Date},name:e,arg:n};if(a()){if("postMessage"===e){var r={data:n};return window.__uniapp_x_postMessage?window.__uniapp_x_postMessage(r):window.__uniapp_x_.postMessage(JSON.stringify(r))}var d={type:"WEB_INVOKE_APPSERVICE",args:{data:i,webviewIds:t}};window.__uniapp_x_postMessage?window.__uniapp_x_postMessageToService(d):window.__uniapp_x_.postMessageToService(JSON.stringify(d))}else if(o()){if("postMessage"===e){var s={data:[n]};return window.__dcloud_weex_postMessage?window.__dcloud_weex_postMessage(s):window.__dcloud_weex_.postMessage(JSON.stringify(s))}var w={type:"WEB_INVOKE_APPSERVICE",args:{data:i,webviewIds:t}};window.__dcloud_weex_postMessage?window.__dcloud_weex_postMessageToService(w):window.__dcloud_weex_.postMessageToService(JSON.stringify(w))}else{if(!window.plus)return window.parent.postMessage({type:"WEB_INVOKE_APPSERVICE",data:i,pageId:""},"*");if(0===t.length){var u=plus.webview.currentWebview();if(!u)throw new Error("plus.webview.currentWebview() is undefined");var g=u.parent(),v="";v=g?g.id:u.id,t.push(v)}if(plus.webview.getWebviewById("__uniapp__service"))plus.webview.postMessageToUniNView({type:"WEB_INVOKE_APPSERVICE",args:{data:i,webviewIds:t}},"__uniapp__service");else{var c=JSON.stringify(i);plus.webview.getLaunchWebview().evalJS('UniPlusBridge.subscribeHandler("'.concat("WEB_INVOKE_APPSERVICE",'",').concat(c,",").concat(JSON.stringify(t),");"))}}},d={navigateTo:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;r("navigateTo",{url:encodeURI(n)})},navigateBack:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.delta;r("navigateBack",{delta:parseInt(n)||1})},switchTab:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;r("switchTab",{url:encodeURI(n)})},reLaunch:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;r("reLaunch",{url:encodeURI(n)})},redirectTo:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;r("redirectTo",{url:encodeURI(n)})},getEnv:function(e){a()?e({uvue:!0}):o()?e({nvue:!0}):window.plus?e({plus:!0}):e({h5:!0})},postMessage:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};r("postMessage",e.data||{})}},s=/uni-app/i.test(navigator.userAgent),w=/Html5Plus/i.test(navigator.userAgent),u=/complete|loaded|interactive/;var g=window.my&&navigator.userAgent.indexOf(["t","n","e","i","l","C","y","a","p","i","l","A"].reverse().join(""))>-1;var v=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 p=window.tt&&window.tt.miniProgram&&/toutiaomicroapp/i.test(navigator.userAgent);var _=window.wx&&window.wx.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var m=window.qa&&/quickapp/i.test(navigator.userAgent);var f=window.ks&&window.ks.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var l=window.tt&&window.tt.miniProgram&&/Lark|Feishu/i.test(navigator.userAgent);var E=window.jd&&window.jd.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var x=window.xhs&&window.xhs.miniProgram&&/xhsminiapp/i.test(navigator.userAgent);for(var S,h=function(){window.UniAppJSBridge=!0,document.dispatchEvent(new CustomEvent("UniAppJSBridgeReady",{bubbles:!0,cancelable:!0}))},y=[function(e){if(s||w)return window.__uniapp_x_postMessage||window.__uniapp_x_||window.__dcloud_weex_postMessage||window.__dcloud_weex_?document.addEventListener("DOMContentLoaded",e):window.plus&&u.test(document.readyState)?setTimeout(e,0):document.addEventListener("plusready",e),d},function(e){if(_)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(g){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(v)return document.addEventListener("DOMContentLoaded",e),window.swan.webView},function(e){if(p)return document.addEventListener("DOMContentLoaded",e),window.tt.miniProgram},function(e){if(m){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){if(f)return window.WeixinJSBridge&&window.WeixinJSBridge.invoke?setTimeout(e,0):document.addEventListener("WeixinJSBridgeReady",e),window.ks.miniProgram},function(e){if(l)return document.addEventListener("DOMContentLoaded",e),window.tt.miniProgram},function(e){if(E)return window.JDJSBridgeReady&&window.JDJSBridgeReady.invoke?setTimeout(e,0):document.addEventListener("JDJSBridgeReady",e),window.jd.miniProgram},function(e){if(x)return window.xhs.miniProgram},function(e){return document.addEventListener("DOMContentLoaded",e),d}],M=0;M<y.length&&!(S=y[M](h));M++);S||(S={});var P="undefined"!=typeof uni?uni:{};if(!P.navigateTo)for(var b in S)i(S,b)&&(P[b]=S[b]);return P.webView=S,P}));

index.html

<!doctype html>
<html>
	<head>
		<meta charset="UTF-8" />
		<script>
			window.globalCallbackForApp = function (value) {
				console.log("子应用接收父应用的实时消息【全局】", value);
			};

			var coverSupport =
				"CSS" in window &&
				typeof CSS.supports === "function" &&
				(CSS.supports("top: env(a)") || CSS.supports("top: constant(a)"));
			document.write(
				'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
					(coverSupport ? ", viewport-fit=cover" : "") +
					'" />',
			);
		</script>
		<script src="/src/static//js/hybrid_html_uni.webview.1.5.5.js"></script>
		<!-- <script type="text/javascript" src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=PB3X34j5vGW07DLETDN11qtTrrV1fn8M"></script> -->
		<script type="text/javascript">
			window.webViewUni = uni;
			// 待触发 `UniAppJSBridgeReady` 事件后,即可调用 uni 的 API。
			document.addEventListener("UniAppJSBridgeReady", function () {
				// webViewUni.postMessage({
				// 	data: {
				// 		action: "message",
				// 	},
				// });
				// webViewUni.getEnv(function (res) {
				// 	console.log("当前环境:" + JSON.stringify(res));
				// });
			});
		</script>
		<title></title>
		<!--preload-links-->
		<!--app-context-->
	</head>
	<body>
		<div id="app"><!--app-html--></div>
		<script type="module" src="/src/main.ts"></script>
	</body>
</html>

APP端代码(选项式)

<template>
  <web-view
    ref="webview"
    src="http://11.2.244.245:9901/pages/home/list-user/index"
    :fullscreen="false"
    id="m-webview"
  ></web-view>
</template>

<script lang="ts">
export default {
  data() {
    return {
      webUrl: '',
      wvNode: null,
    }
  },
  onReady() {
    // #ifdef APP-PLUS
    var currentWebview = this.$scope.$getAppWebview() //此对象相当于html5plus里的plus.webview.currentWebview()。在uni-app里vue页面直接使用plus.webview.currentWebview()无效
    setTimeout(() => {
      this.wvNode = currentWebview.children()[0]
      console.log('currentWebview', currentWebview)
      console.log('this.wvNode.evalJS1', this.wvNode)
      console.log('this.wvNode.evalJS', typeof this.wvNode.evalJS)
      console.log('执行')
      this.wvNode.evalJS('msgFromApp("来着父组件的消息")')
    }, 1000)
    // #endif
  },
  onHide() {
    // console.log('patrol-h5-onHide')
    // #ifdef APP-PLUS
    const name = 'stop'
    this.wvNode.evalJS("msgFromApp('" + name + "')")
    // console.log('---currentWebview---wvNode---onHide=',this.wvNode.evalJS)
    // #endif
  },
}
</script>

<style lang="scss" scoped></style>

https://uniapp.dcloud.net.cn/tutorial/page.html#getappwebview

参考链接

https://juejin.cn/post/7230727650259025980

人工智能学习网站 

https://chat.xutongbao.top

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2127482.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构-二叉树-基础知识

数据结构-二叉树-基础知识 1.树1.1什么是树1.2基本概念子节点、父节点叶节点节点的度树的高度/深度节点的子孙、祖先 1.3树与非树1.4如何实现1.5实例 2.二叉树2.1什么是二叉树2.2特殊的二叉树满二叉树完全二叉树 2.3性质层数度节点 2.4存储结构 1.树 1.1什么是树 树型结构是一…

C#笔记10 Thread类怎么终止(Abort)和阻止(Join)线程

Thread类 C#笔记8 线程是什么&#xff1f;多线程怎么实现和操作&#xff1f;-CSDN博客 C#笔记9 对线程Thread的万字解读 小小多线程直接拿下&#xff01;-CSDN博客 上次说过怎么简单的使用多线程&#xff0c;怎么创建多线程&#xff0c;但是没有具体分析它的终止和释放。 线…

【C++题解】1330. 求最大梯形的面积

欢迎关注本专栏《C从零基础到信奥赛入门级&#xff08;CSP-J&#xff09;》 问题&#xff1a;1330. 求最大梯形的面积 类型&#xff1a;二维数组 题目描述&#xff1a; 从键盘读入 n ( 3≤n≤100 )个梯形的上底、下底和高&#xff0c;请问这 n 个梯形中&#xff0c;最大面积…

3.ChatGPT在教育领域的应用:教学辅助与案例分享(3/10)

ChatGPT在教育领域的应用&#xff1a;教学辅助与案例分享 引言 在21世纪的教育领域&#xff0c;技术革新正以前所未有的速度改变着传统的教学和学习方式。随着人工智能&#xff08;AI&#xff09;的快速发展&#xff0c;教育技术&#xff08;EdTech&#xff09;领域迎来了新的…

“后期分块”:用长上下文嵌入模型拯救文本检索

论文&#xff1a;Late Chunking: Contextual Chunk Embeddings Using Long-Context Embedding Models地址&#xff1a;https://arxiv.org/abs/2409.04701 研究背景 研究问题&#xff1a;这篇文章要解决的问题是文本块嵌入在处理长文本时丢失上下文信息的问题。具体来说&#xf…

信刻光盘安全隔离与信息交换系统

随着各种数据传输、储存技术、信息技术的快速发展&#xff0c;保护信息安全是重中之重。军工、政府、部队及企事业单位等利用A网与B网开展相关工作已成为不可逆转的趋势。针对于业务需要与保密规范相关要求&#xff0c;涉及重要秘密信息&#xff0c;需做到安全的物理隔离&#…

队列的详细操作

1.循环队列--队列的顺序表示和实现 #include<stdio.h> #define MAXQSIZE 100 typedef struct {int* base;int front;int rear; }SqQueue;int InitQueue(SqQueue& Q) {Q.base new int[MAXQSIZE];//为队列分配一个最大容量为MAXSIZE的数组空间if (!Q.base)return -1;…

QXml 使用方法

VS2019 QT 编译工具链问题解决 使用winqtdeploy.exe 打包环境就可以正常运行&#xff0c;缺少某一个运行库引起的 简易使用python脚本编译运行 Python3 中的 slots 和 QT 中的 slots 宏定义重复, 放在不同的文件中进行调用可以避免 还是比较习惯从源码包引入&#xff08;方便定…

OpenAI新“草莓”模型即将发布,推理模式引发关注

OpenAI发布“草莓”模型的消息引发广泛关注。这个新模型将在未来两周内亮相&#xff0c;将为ChatGPT等产品带来全新的技术支持。草莓模型的推理模式具有独特性&#xff0c;能够仿效人类思维&#xff0c;在生成响应之前进行拟人化思考。其推理过程通常需要10到20秒&#xff0c;这…

2_foc闭环调试_ADC电流采样与滤波及pid数据结构

1、ADC电流采样 上次添加了编码器获取电角度的程序&#xff0c;将之前开环控制的角度进行了替换&#xff0c;这次再将电流采样添加进来&#xff0c;之后就可以利用这样一个有反馈的系统进行电流环PI控制器参数调试。 之前写过ADC&#xff0b;DMA电流采样的stm32库函数程序&…

《 C++ 修炼全景指南:八 》智能指针大揭秘:从 auto_ptr 到 unique_ptr shared_ptr 的进化之路

1、引言 在 C 编程中&#xff0c;内存管理历来是复杂且容易出错的部分。手动管理动态分配的内存不仅会导致内存泄漏&#xff0c;还会引发悬空指针和双重释放等问题。如何有效地管理动态内存&#xff0c;避免内存泄漏和未定义行为&#xff0c;往往是困扰初学者和资深开发者的难…

常见 HTTP 状态码详解与Nginx 文件上传大小限制

在我们日常使用 Nginx 搭建网站或应用服务时&#xff0c;可能会遇到很多与文件上传和请求响应相关的问题。今天我们就来聊聊 如何限制文件上传的大小&#xff0c;并介绍一些常见的 HTTP 状态码 及其在 Nginx 中的处理方式。 一、文件上传大小限制 有时&#xff0c;我们需要限…

Web3的崛起与智能合约的角色

随着Web3的发展&#xff0c;去中心化网络逐渐取代了以往的集中控制互联网模式。这一转变不仅强调了用户的自治权和隐私保护&#xff0c;还引入了智能合约这一核心技术。智能合约基于区块链技术&#xff0c;能够自动执行合约条款&#xff0c;无需中介干预&#xff0c;从而确保了…

git下载安装windows

https://git-scm.com/download/win 接下来傻瓜式安装就可以了

Django创建模型

1、根据创建好应用模块 python manage.py startapp tests 2、在models文件里创建模型 from django.db import modelsfrom book.models import User# Create your models here. class Tests(models.Model):STATUS_CHOICES ((0, 启用),(1, 停用),# 更多状态...)add_time mode…

RAR压缩包原密码过于简单如何修改密码?

RAR压缩包作为一种常见的文件压缩格式&#xff0c;广泛应用于文件传输和存储中。为了保障文件的安全性&#xff0c;用户经常会给RAR压缩包设置密码。但有时我们觉得原密码过于简单&#xff0c;想要修改成一个比较复杂的密码&#xff0c;这时我们要如何修改让人压缩包密码呢&…

<<编码>> 第 5 章 绕过拐弯的通信(Seeing Around Corners) 示例电路

灯泡通讯电路 info::操作说明 鼠标单击开关切换开合状态 primary::在线交互操作链接 https://cc.xiaogd.net/?startCircuitLinkhttps://book.xiaogd.net/code-hlchs-examples/assets/circuit/code-hlchs-ch05-01-communication-circuit.txt 双边灯泡通讯电路 info::操作说明 鼠…

Windows一键安装Mysql数据库|非官方复杂安装,解压即可,操作简单

我们都知道在官方安装mysql数据库极其复杂&#xff0c;还极大概率遇到各种问题&#xff0c;今天教大家只要解压就可安装完数据库&#xff0c;操作及其简单绿色。 版本包括了mysql8或mysql5&#xff0c;各位各取所需即可。 不管你之前是否安装过数据库&#xff0c;只要端口330…

Ai+若依(智能售货机运营管理系统---帝可得)--货道关联商品【08篇---0004:关联商品】

货道关联商品 需求 对智能售货机内部的货道进行商品摆放的管理 此功能涉及四个后端接口 查询设备类型&#xff08;已完成&#xff09; 查询货道列表&#xff08;待完成&#xff09; 查询商品列表&#xff08;已完成&#xff09; 货道关联商品&#xff08;待完成&#xff0…

个人学习笔记5-2:动手学深度学习pytorch版-李沐

#深度学习# #人工智能# #神经网络# 卷积神经网络&#xff08;convolutional neural network&#xff0c;CNN&#xff09; 6.4 多输入多输出通道 6.4.1 多输入通道 当输入包含多个通道时&#xff0c;需要构造一个与输入数据具有相同输入通道数的卷积核&#xff0c;以便与输入…