牟平建设局网站,潍坊住房与城市建设部网站,网站开发的架构,windows优化大师是官方的吗一.知识点(1).我们可以通过postMessage(发送方)和onmessage(接收方)这两个HTML5的方法, 来解决跨页面通信问题#xff0c;或者通过iframe嵌套的不同页面之间的通信a.父页面代码如下div v-ifsrc classiframeiframerefiframeid… 一.知识点(1).我们可以通过postMessage(发送方)和onmessage(接收方)这两个HTML5的方法, 来解决跨页面通信问题或者通过iframe嵌套的不同页面之间的通信a.父页面代码如下div v-ifsrc classiframeiframerefiframeidiframewidth100%height600loadinglazy:srcsrcframeborder0scrollingnomarginheight0marginwidth0loadloaded/iframe
/diva1.父页面向子页面发送信息(两种方法)第一种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-ifhasApprovedtypeprimarysizesmallclicksubmit(Approved)审批通过
/el-button2.方法如下// 审批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}})})},
}