关于iframe一些通讯的记录(可适用工作流审批,文中有项目实践,欢迎咨询)

news/2024/5/13 10:28:17/文章来源:https://blog.csdn.net/weixin_42125732/article/details/129188603

一.知识点

(1).我们可以通过postMessage(发送方)和onmessage(接收方)这两个HTML5的方法, 来解决跨页面通信问题,或者通过iframe嵌套的不同页面之间的通信

a.父页面代码如下

<div v-if="src" class="iframe"><iframeref="iframe"id="iframe"width="100%"height="600"loading="lazy":src="src"frameborder="0"scrolling="no"marginheight="0"marginwidth="0"@load="loaded"></iframe>
</div>

a1.父页面向子页面发送信息(两种方法)

第一种

const iframe = document.getElementId('iframe')//id
//第一个参数是发送的消息,无格式要求;第二个参数是域名限制,当不限制域名时填写*
// 后面的 * 号就是处理跨域问题的,任何域名都不会出现跨域问题
// 传递的参数可以是数组,对象,字符串等 
iframe.contentWindow.postMessage('你需要传的数据', "*"); //数据比如({},'*'),('123','*')
// 也可以指定传送域名地址,这个域名不会出现跨域问题,写父页面(接收)域名地址
iframe.contentWindow.postMessage("需要传递的参数", 'http://0.0.0.0:8080')

第二种

this.$refs.iframe.contentWindow.postMessage(workDetailsData.workflowList,'*')

a2.子页面接收父页面收到的信息

 * 函数防抖* @param fn* @param interval* @returns {Function}* @constructor*/
export const Debounce = (fn, t) => {let delay = t || 500let timerreturn function () {let args = argumentsif (timer) {clearTimeout(timer)}timer = setTimeout(() => {timer = nullfn.apply(this, args)}, delay)}
}import { Debounce } from '@/utils/public.js'
mounted() {window.onmessage = this.handleMesg// addEventListener触发多次问题// window.addEventListener('message', this.handleMesg)}
},//防抖处理
handleMesg: Debounce(function (e) {//这里做接收数据的操作if(e){console.log(e.data)
}}),

a.3子页面(iframe加载的页面)向父页面传递消息

window.parent.postMessage({string: '我是iframe里面的数据'}, "*");

a.4父页面接收子页面传递的消息

window.onmessage = function(event){console.log(event.data.string) //我是iframe里面的数据
}

a.5 父页面接收子页面传递的消息(第二种)

//监听单个事件
window.addEventListener('message', function (msg) {console.log(msg.data.string)
})

二.项目实践

1.效果图

编辑

编辑

编辑

逻辑如下

1.首先点击审批通过按钮,调用方法

<el-buttonv-if="hasApproved"type="primary"size="small"@click="submit('Approved')">审批通过
</el-button>

2.方法如下

// 审批submit(data) {this.operateStatus = data //传过来的状态储存起来if (this.suspended) { //默认是false  请求详情接口时会根据后端返回这个字段判断他是否挂起this.$message.error('该任务已挂起,无法进行操作!')return}if (data === '撤回') {this.confirmSubmit()return}let label = data === 'Approved' ? '审批通过' : '审批拒绝'this.assignee_schema_model.comment =data === 'Approved' ? '批准' : '拒绝'this.dialogTitle = `确认是否${label}`this.msgContent = `确认${label}吗?`this.visible = true //打开弹窗},
弹窗如下

3.点击确定调用接口方法,调用接口时进行一些判断操作如下

  confirmSubmit() {let data = this.operateStatusthis.isLoading = trueif (data === 'Approved' || data == 'Rejected') {const params = { //审批流接口需要的参数variables: [{name: 'approveResult',value: data === 'Approved' ? 'Approved' : 'Rejected', //判断是同意还是拒绝},{name: 'comment',value: this.assignee_schema_model.comment,},{name: 'isWithdraw',value: '0',},],action: 'complete',comment: this.assignee_schema_model.comment,currentTaskId: this.$route.query.id,}if (!this.assignee_schema_model.comment) { //判断是否写了批注 不能为空this.$message.error('请输入批注!')this.isLoading = falsereturn}//重点 这里假如你是需要在自己的页面,比如商品详情页面,即iframe的页面自己调用自己中心的后端接口,不通过公共的审批接口时,需要进入这里,this.isPostMsg这个数据需要自己判断是否需要进入if (this.isPostMsg && data == 'Approved') {// 审批动作在iframe页面中完成this.$refs.iframe.contentWindow.postMessage( //向iframe 页面传递信息{status: data,value: this.assignee_schema_model.comment,params: params,},'*')this.visible = falsethis.isLoading = falsewindow.addEventListener('message', this.handleMesg) //接收iframe页面传递过来的信息return //不往下执行 即不调用公共审批接口}if (!this.src) { //判断配置console.log('审批流配置问题,formKey为空')this.$message.error('流程配置问题,/activiti/task接口返回的formKey为空')this.visible = falsethis.isLoading = falsereturn}if (!this.isOpenIframe(this.src)) {//没有被审批流程的菜单权限this.$message.error(this.authMenuMsg)this.visible = falsethis.isLoading = falsereturn}taskAction(params) //调用公共审批接口 (包含了同意和拒绝) 根据定义的参数判断.then((res) => {if (res.failed === true) {this.$message.error(res.message || '操作失败,请联系管理员')this.isLoading = false} else {this.$message.success('操作成功')this.visible = falsethis.isLoading = falsethis.$store.dispatch( //关闭当前页面路由'tabsBar/delVisitedRoute',this.$route.fullPath)this.$router.push(`/tcl/tof/message/workflow/wait-list`) //跳转到待办列表页面}}).catch((error) => {this.$message.error(error)this.isLoading = false})} else {// 撤回backAction(this.$route.query.id) //撤回流程公共 接口.then((res) => {if (res.failed === true) {this.$message.error(res.message || '操作失败,请联系管理员')this.isLoading = false} else {this.$message.success('操作成功')this.$store.dispatch('tabsBar/delVisitedRoute',this.$route.fullPath)// this.$router.go(-1)this.visible = falsethis.isLoading = falsethis.$router.push(`/tcl/tof/message/workflow/wait-list`)}}).catch((error) => {this.$message.error(error)this.isLoading = false})}},

4.父页面的handleMesg方法(重点交互)

//防抖 (debounce): 将多次高频操作优化为只在最后一次执行,通常使用的场景是:用户输入,只需再输入完成后做一次输入校验即可。
//防抖处理 高频调用handleMesg: Debounce(function (e) {if (e.data.type == 'getDataDetail') {//子页面想要获取待办详情接口数据 会主动发送一个事件过来//如判断type是哪个页面过来的//这里向子页面发送数据回去this.$refs.iframe.contentWindow.postMessage(workDetailsData.workflowList, //待办详情接口返回的数据'*')}//这里可以自定义提示信息的操作//iframe子页面会发送一个方法过来 如第五点if (e.source) {if (e.data.status == 'Approved') {//补充知识//getElementsByClassName() 方法返回文档中所有指定类名的元素集合,作为 NodeList 对象。//NodeList 对象代表一个有顺序的节点列表。NodeList 对象 我们可通过节点列表中的节点索引号来访问列表中的节点(索引号由0开始)。//提示: 你可以使用 NodeList 对象的 length 属性来确定指定类名的元素个数,并循环各个元素来获取你需要的那个元素。let doms = document.getElementsByClassName('el-message')[0]if (doms == undefined) {this.$message.success('审批通过')}this.visible = falsethis.$store.dispatch('tabsBar/delVisitedRoute',this.$route.fullPath)if (this.$route.query.type === 'workflow')this.$router.push(`/tcl/tof/order/sales/workflow`)else this.$router.push(`/tcl/tof/message/workflow/wait-list`)} else if (e.data.status == 'Rejected') {let doms = document.getElementsByClassName('el-message')[0]if (doms == undefined) {this.$message.success('审批拒绝')}this.visible = falseif (this.$route.query.type === 'workflow')this.$router.push(`/tcl/tof/order/sales/workflow`)else this.$router.push(`/tcl/tof/message/workflow/wait-list`)} } else if (e.data.status == 'innerError') {let msgObj = e.datathis.$message({type: msgObj.msgType,message: msgObj.msg,})}}}),

5.子页面方法

that.postMsgToFrame('缺少附件', 'warning')
postMsgToFrame(msg, errType) {if (this.isPorcess) {window.parent.postMessage({type: 'custAddMsg',status: 'innerError',msgType: errType,msg: msg,},'*')} else {this.$message({type: errType,message: msg,})}},

子页面一开始要获取审批流待办详情接口数据来进行一些判断如下

mounted() {// console.log('workDetailsData', workDetailsData)//首先向父页面主动发送事件if (this.$route.query.type == 'delay') {window.parent.postMessage({type: 'getDataDetail',},'*')//父页面发送事件过来,这里接收事件和数据,进行对应的操作,如判断该字段在哪个节点是否需要显示window.addEventListener('message', (e) => {if (e.data) {let showNode = []if (this.options.nodeStatus && this.options.nodeStatus.length > 0) {this.options.nodeStatus.forEach((item) => {showNode.push(item.value)})console.log('这里的数据看看', showNode)if (showNode.indexOf(e.data.name) != -1) {obsData.isFlagShowCol = true}}}})}},

配置平台配置流程

iframe页面判断审批同意接口是否调用自己中心的后端接口

computed: {isPorcess: {get() {let ll = this.$route.queryif (ll.custPostMsgFlg && ll.custPostMsgFlg.indexOf('true') > -1) {return true} else {return false}},},
}

进入页面在mounted判断,需要节点都挂载完毕,然后在方法methods中调用审批方法,是由父页面点击审批通过发送事件过来进行调用

mounted() {if (this.isPorcess) {window.addEventListener('message', this.handleMesg)}
}
methods: {// 点击审批async handleMesg(e) {console.log('e', e)if (e.data.status === 'Approved') { //判断是否同意// this.$refs.Address.$refs.tabs.validate()this.examineApprove()}},async examineApprove() {//先进行表单必填校验操作 通过才调用接口let flag = await this.$refs.Address.validateForm()this.$refs['commentForm'].validate((isPass) => {this.schema_model.comment = this.commentForm.comment //批注自定义this.$refs['filterForm'].validate((valid) => {//校验if (valid && flag && isPass) {const loading = this.$baseLoading({target: 'document.body.tree',})subsidyPriceProcess(this.schema_model).then((res) => {if (res.success == false) {loading.close()this.$message.error('审批不通过,接口报错')} else {loading.close()//iframe 向父组件传值window.parent.postMessage({type: 'commodityApprove',status: 'Approved',},'*')}})} else {this.$message({type: 'error',message: '表单校验不通过!',})return false}})})},
}

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux——进程概念(进程状态)

目录 进程状态 三态模型 五态模型 七态模型 Example eg1:阻塞态&#xff1a;等待某种资源的过程 eg2:挂起态 Linux内核源代码 Linux进程状态查看 Linux运行状态 R运行状态&#xff08;running&#xff09;: S睡眠状态&#xff08;sleeping)&#xff1a; D磁盘休眠状…

HEVC 编码速率控制

视频传输带宽通常都会受到一定的限制&#xff0c;为了在满足通信带宽和传输时延限制的情况下有效传输视频数据&#xff0c;保证视频业务的播放质量&#xff0c;需要对视频编码过程进行速率控制&#xff0c;所谓速率控制&#xff0c;就是通过选择一系列编码失真尽量小&#xff0…

一篇了解分布式id生成方案

系统唯一ID是我们在设计一个系统的时候常常会遇见的问题&#xff0c;也常常为这个问题而纠结。生成ID的方法有很多&#xff0c;适应不同的场景、需求以及性能要求。所以有些比较复杂的系统会有多个ID生成的策略。下面就介绍一些常见的ID生成策略。 1.数据库自增长序列或字段 …

DCL单例模式是如何保证数据安全的?

承接上文证明CPU指令是乱序执行的DCL单例&#xff08;Double Check Lock&#xff09;到底需不需要volatile&#xff1f;new对象这一步&#xff0c;对应着汇编层面的这3个指令&#xff0c;指令0是申请空间&#xff0c;设置默认值&#xff1b;指令7是执行构造方法&#xff0c;设置…

计算机网络概述 第二部分

5.网络分层 ①OSI 7层模型 数据链路层 (Data Link Layer) 实现相邻&#xff08;Neighboring&#xff09;网络实体间的数据传输 成帧&#xff08;Framing&#xff09;&#xff1a;从物理层的比特流中提取出完整的帧 错误检测与纠正&#xff1a;为提供可靠数据通信提供可能 …

stm32f407探索者开发板(二十一)——窗口看门狗

文章目录一、窗口看门狗概述1.1 看门狗框图1.2 窗口看门狗工作过程总结1.3 超时时间1.4 为什么需要窗口看门狗1.5 其他注意事项二、常用寄存器和库函数2.1 控制寄存器WWDG_ CR2.2 配置寄存器WWDG_ CFR2.3 状态寄存器WWDG_SR三、手写窗口看门狗3.1 配置过程3.2 初始化窗口看门狗…

【微信小程序】-- 常用视图容器类组件介绍(六)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#…

LeetCode 725. 分隔链表

LeetCode 725. 分隔链表 难度&#xff1a;middle\color{orange}{middle}middle 题目描述 给你一个头结点为 headheadhead 的单链表和一个整数 kkk &#xff0c;请你设计一个算法将链表分隔为 kkk 个连续的部分。 每部分的长度应该尽可能的相等&#xff1a;任意两部分的长度差…

绿通科技在创业板开启申购:超额募资约19亿元,收入依赖贴牌

2月23日&#xff0c;广东绿通新能源电动车科技股份有限公司&#xff08;下称“绿通科技”&#xff0c;SZ:301322&#xff09;开启申购。据贝多财经了解&#xff0c;绿通科技本次上市的发行价为131.11元/股&#xff0c;发行数量为1749万股&#xff0c;市盈率73.75倍。 按发行价…

逆向 x品会 edata

逆向 x品会 edata 版本 7.88.6 帖子底部有参考说明 charles 抓包 目标字段 edata edata 搜索关键字 跟进找到是edata >>> KeyInfo native esNav 方法 private static native String esNav(Context context, String str, String str2, String str3, int i); …

XX项目自动化测试方案模板,你学会了吗?

目录 1、引言 2、自动化实施目标 3、自动化技术选型 4、测试环境需求 5、人员进度安排 总结感谢每一个认真阅读我文章的人&#xff01;&#xff01;&#xff01; 重点&#xff1a;配套学习资料和视频教学 1、引言 文档版本 版本 作者 审批 备注 V1.0 Vincent XXX …

不会前端没事,用GWT Boot和Spring Boot构建Web程序

本文介绍了一种使用Java构建Web应用程序的方式&#xff0c;其中GWT或者J2CL是必不可少的&#xff0c;另外还有多个UI框架可以配套使用&#xff0c;比如Domino UI、VueGWT、GWT Material Design (GMD)&#xff0c;React4J、WebFX&#xff0c;还有一些活跃低的框架GWTBootstrap3、…

【解决报错】‘jupyter‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件

在当前路径下使用cmd打开后&#xff0c;输入jupyter notebook出现如下错误&#xff1a; 通常可能出现的问题有两种&#xff1a; &#xff08;1&#xff09;你本身就没安装jupyter&#xff0c;如果你配置了anaconda&#xff0c;就自带jupyter&#xff0c;直接跳到问题2。如果确…

Apache Commons FileUpload Apache Tomcat拒绝服务漏洞解决方案

近日&#xff0c;安全狗应急响应中心关注到Apache官方发布安全公告&#xff0c;披露在Apache Commons FileUpload&#xff1c;1.5版本中存在一处拒绝服务漏洞&#xff08;CVE-2023-24998&#xff09;。Commons FileUpload是Apache组织提供的免费的上传组件。由于Apache Commons…

面向对象的一点小想法

接口里的方法可以写也可以不写 如果写的话&#xff0c;那么得是默认方法&#xff0c;需要在前面加个default 对于默认方法&#xff0c;能够重写&#xff0c;或者直接继承&#xff08;也就是直接用&#xff09; 比如下面&#xff1a; 就直接调用了接口的默认函数nibuhao&#…

R统计绘图-NMDS、环境因子拟合(线性和非线性)、多元统计(adonis2和ANOSIM)及绘图(双因素自定义图例)

这个推文也在电脑里待了快一年了&#xff0c;拖延症患者&#xff0c;今天终于把它发出来了。NMDS分析过程已经R统计-PCA/PCoA/db-RDA/NMDS/CA/CCA/DCA等排序分析教程中写过了。最近又重新看了《Numerical Ecology with R》一书,巩固一下知识&#xff0c;正好重新整理了一下发出…

Nacos源码启动

一、下载源码 为保证速度&#xff0c;国内推荐使用gitee&#xff1a;https://gitee.com/mirrors/Nacos.git 二、导入IDE中 参考之前文章配置国内Maven私服&#xff0c;快速更新工程。 三、启动过程&#xff0c;各种问题 找到启动入口&#xff1a; 先直接启动测试下&#xff…

oscp渗透测试认证该从哪里学起

当我决定要考OSCP时就马上打开浏览器&#xff0c;试图一下弄清楚课程内容和通过考试的方法&#xff0c;我不断的将指南和资源添加到书签中。渐渐的书签里存了许多资料&#xff0c;以至于我不知道从哪里开始学&#xff0c;学习命令吗&#xff1f;我学习编码吗&#xff1f;我使用…

北京/东莞/广州/深圳2023年上半年软考(中/高级)报名>>>

软考是全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff08;简称软考&#xff09;项目&#xff0c;是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试&#xff0c;既属于国家职业资格考试&#xff0c;又是职称资格考试。 系统集成…

扩展学习之时间戳趣谈

目录 一、介绍 二、转换工具 三、获取Unix时间戳的指令 四、普通时间转Unix时间戳 五、扩展 一、介绍 时间戳&#xff1a;一份数据在特定时间点存在的可验证的数据。 Unix时间戳&#xff08;英文为Unix epoch, Unix time, POSIX time 或 Unix timestamp&#xff09;&…