- 本文记录一下工作中关于双标签页通信问题
- 涉及的技术:
vue
webpack
postMessage iframe
- 如今网上已经有许多关于多标签页通信技术文档,但终究不是十分适用自己的需求,所以实践出真知,我来总结一下自己的经验
- 了解一下
postMessage
:MDN-postMessage
主要是下面2个API
onmessage
window.onmessage = e =>{
console.log(e.data) //接收到的信息在e.data里
}
postMessage
window.postMessage({event:'changePoroject',data:{name:'小强'}},location.origin)
注意点说明:
1.window
-指的是需要传递消息页面的引用
2.传递的第二个参数官方说明是-可以接收消息的页面(一般指url
)
iframe
<iframe src='baidu.com' ref='iframe1' id='iframe><iframe>
获取iframe
的window
对象
vue
this.$refs.iframe1.contentWindow
-
iframe
内外传递信息也是通过postmesage
和postMessage
- 下面来聊一下两个
Tab
页通信的实现方式和注意点
- 约定数据格式-也就是
mesasge
选项的格式
{event:'changePoroject',data:{name:'小强'}}
event
为我要传递的事件,data
我要传递的参数,这样就能像监听事件一样来交互
-
onmessage
监听事件-放在mounted
或created
里 -
window.open
打开子页面- 子页面初始化(包括初次打开和页面刷新)时,向父页面发送请求,初始化数据;监听子页面
onload
事件初始化数据,有时间上的误差,不能及时初始化子页面数据,所以要在mounted
或created
里向父页面发送初始化请求 - 父页面点击关闭和刷新页面时,子页面引用对象调用
close
方法,childPage.close()
- 监听子页面关闭,循环监听子页面
closed
值,为true
则改变父页面的相关状态 - 子页面监听父页面的刷新状态,如果父页面刷新-关闭自己-
window.close()
- 在子页面里-
window.opener
代表了父页面,可以使用window.opener.postMessage
来向父页面发送消息
- 子页面初始化(包括初次打开和页面刷新)时,向父页面发送请求,初始化数据;监听子页面
-
webpack
初始化时,onmessage
会监听到webpack发送的请求
,所以接收到数据后要先判断数据格式,然后再进行操作
下面是两个页面交互的部分代码
//打开分屏页面
this.childPage = window.open(this.secondUrl,‘child’)
let loop = setInterval(()=>{
if(this.childPage.closed){
clearInterval(loop)
.... //监听子页面关闭,父页面做出相应的改动
}
},1000)
//主页面
mounted(){
window.onmessage = e => {
if(typeof e.data === 'string'){
console.log('传递无效信息')
}else {
if(e.data.event){
console.log('正常发送数据')
swith(e.data.event){
case 'getData':
//子页面初始化获取数据
}
....//其他事件
}
}
}
}
//向子页面发送数据
this.childPage.postMessage({event:'initData',data:this.transforData},location.origin)
//子页面初始化
mounted(){
window.onmessage = e => {
if(typeof e.data === 'string'){
console.log('传递无效信息')
}else {
if(e.data.event){
console.log('正常发送数据')
swith(e.data.event){
case 'initData':
this.initial(e.data.data)
//子页面响应父页面数据变化
}
....//其他事件
}
}
}
window.opener.postMessage({event:'getData'})//初始化向父页面索取数据
window.opener.onunload = () => {
window.close()//监听到父页面关闭后,子页面自动关闭
}
}
下面是每个页面的iframe
交互-两个页面间的iframe
交互只是需要本页面监听iframe
事件后,向另一个页面发送数据
<iframe :src='/model/ppt.htm' ref='iframe' id='iframe><iframe>
//向iframe发送数据
this.$refs.iframe.contentWindow.postMessage({event:'onSelectDate',data:this.date},this.$refs.iframe1.src)
//监听iframe的事件也放在mounted的onmessage里
本文正在参加“写编程博客瓜分千元现金”活动,关注公众号“饥人谷”回复“编程博客”参与活动。
网友评论