每天进步一点点—项目中的问题
老板让我做一个需求,一个项目分成两个模块,控制台和会务模块,刚开始的时候是一个vue项目中写的,写到最后,老板说,你把控制台和会务模块拆分出来,控制台不用变,以后只要改会务模块,可以单独打包上线,并且以后还可以添加其他模块,从控制台进入,也是单独打包上线,我当时一想,单独打包上线好像vue里面有这个依赖,改里面的main.js以及其他的配置文件,当时找了几天,百度到各种各样的多模块开发项目,然后我一试,配置的一塌糊涂,根本运行不起来,于是乎,在最后阶段尝试用iframe嵌套会务模块,其实当时根本不知道iframe咋用,用了半天时间,终于搞好了。所以整体思路是,从控制台登录得到令牌,进入会务模块的时候把令牌传给它,这样会务模块才能打开以及发送请求。
控制台项目创一个页面,此页面里面有iframe标签嵌套会务模块项目
<template>
<div class="meeting_box">
<iframe frameborder="0" width="100%" :height="webheight" ref="meetingifram" src='http://192.168.*.***:****'></iframe>
</div>
</template>
这样一进入这个页面,iframe直接打开vue项目,高的话是整个可是屏幕的高,这样是打开了会务模块项目,但是没有传递令牌,应该打不开会务模块项目,所以得向iframe里面传值,这里用的是 window.postMessageMDN官网关于window.postMessage的介绍 使用如下:
mounted(){
//要把菜单,公司数据,令牌给模块
const tokenStr = window.localStorage.getItem('token')
let meetingifram = this.$refs['meetingifram']
// console.log(meetingifram)
if (meetingifram.attachEvent){ //兼容浏览器判断
// console.log(tokenStr,1)
const allmenu = this.allmenudata
const nextmenu = this.nextmenudata
meetingifram.attachEvent("onload", function(){
let iframeWin = meetingifram.contentWindow
iframeWin.postMessage({
tokenStr,
allmenu,
nextmenu,
},'http://192.168.1.109:8081')
//data传递的参数 *写成子页面的域名或者是ip
})
} else {
const allmenu = this.allmenudata
const nextmenu = this.nextmenudata
meetingifram.onload = function(){
let iframeWin = meetingifram.contentWindow
iframeWin.postMessage({
tokenStr,
allmenu,
nextmenu,
},'http://192.168.1.109:8081')
}
// window.location.href='http://192.168.1.109:8081'
}
window.addEventListener('message', (e) => {
if (event.origin !== "http://192.168.1.109:8081")
return
console.log(e,'子组件传我的值')
const path = e.data.data
if(path=='200'){
console.log('我可以调走了吗')
window.location.href='http://192.168.1.109:8081'
}
});
},
我得把令牌和会务模块的菜单发给会务模块,在会务模块接受
//https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
//利用postMessage来回传值的情况下,我们需要判断其数据的来源
//if (event.origin !== "http://192.168.1.109:8083") return
//这个特别重要,因为我整体思路是,用iframe嵌套vue项目,把数据传给vue项目,数据传输好之后,
// 我再给iframe传递一个我收到的信息,iframe父亲收到后,利用window.local.herf='vue项目地址'把当前窗口变成vue项目
window.addEventListener('message',function(e){
if (event.origin !== "http://192.168.1.109:8083")
return
console.log(e,'父组件传来的值')
// console.log(e,111)//子页面接收参数
const data = e.data
const token = e.data.tokenStr
const allmenu =e.data.allmenu
const nextmenu =e.data.nextmenu
// console.log(token)
//页面刷新的时候,本地存储的数据会被删除,所有要判断是否这个值可不可以被放进本地存储
if(token){
window.localStorage.setItem('token',token)
// this.$route.push({
// name:'console'
// })
}
if(allmenu&&allmenu.length!=0){
window.localStorage.setItem('allmenu',JSON.stringify(allmenu))
}
if(nextmenu&&nextmenu.length!=0){
window.localStorage.setItem('nextmenu',JSON.stringify(nextmenu))
}
window.parent.postMessage({
data:'200'
},"http://192.168.1.109:8083/#/meeting/");
})
项目思路如下
控制台通过iframe向会务模块传值,会务模块收到后也向父亲传值
window.parent.postMessage({
data:'200'
},"http://192.168.1.109:8083/#/meeting/");
父亲收到后
window.addEventListener('message', (e) => {
if (event.origin !== "http://192.168.1.109:8081")
return
console.log(e,'子组件传我的值')
const path = e.data.data
if(path=='200'){
console.log('我可以调走了吗')
window.location.href='http://192.168.1.109:8081'
}
});
利用window.location.herf=’'把当前窗口变道vue项目
项目中遇到的坑
1坑
刚开始的时候利用iframe打开会务模块,上面的URL地址不变,还是控制台的地址,在会务模块操作后强制刷新,整个页面回到最初的地方,然后技术群里大佬告诉我,watch会务模块的路由,把路由传给iframe父亲,给iframe的地址加上后面的路由,这样刷新不会导致页面初始化。然后我照做了,watch到路由传给iframe,但是刚开始的我没有写if (event.origin !== "http://192.168.1.109:8083") return
导致iframe addEventListener观察到它发给vue项目的,也观察到正确的,导致出现差错,这个也就写完才发现。反正这个方法out
2坑
后来我发现这个window.location.href
深得我意,就是它了。都在上面,不写了,下班了。必须有if (event.origin !== "http://192.168.1.109:8083")
几天的教训!