0
点赞
收藏
分享

微信扫一扫

vue+webpack+postMessage+iframe双标签页通信

  • 本文记录一下工作中关于双标签页通信问题
  • 涉及的技术:vue webpack postMessage iframe
  • 如今网上已经有许多关于多标签页通信技术文档,但终究不是十分适用自己的需求,所以实践出真知,我来总结一下自己的经验

  1. 了解一下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)

  1. iframe
<iframe src='baidu.com' ref='iframe1' id='iframe><iframe>

获取iframewindow对象

  • vue
this.$refs.iframe1.contentWindow
  • iframe内外传递信息也是通过postmesagepostMessage
  1. 下面来聊一下两个Tab页通信的实现方式和注意点
  • 约定数据格式-也就是mesasge选项的格式
{event:'changePoroject',data:{name:'小强'}}

event为我要传递的事件,data我要传递的参数,这样就能像监听事件一样来交互

  • onmessage监听事件-放在mountedcreated
  • window.open打开子页面
    1. 子页面初始化(包括初次打开和页面刷新)时,向父页面发送请求,初始化数据;监听子页面onload事件初始化数据,有时间上的误差,不能及时初始化子页面数据,所以要在mountedcreated里向父页面发送初始化请求
    2. 父页面点击关闭和刷新页面时,子页面引用对象调用close方法,childPage.close()
    3. 监听子页面关闭,循环监听子页面closed值,为true则改变父页面的相关状态
    4. 子页面监听父页面的刷新状态,如果父页面刷新-关闭自己-window.close()
    5. 在子页面里-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里
举报

相关推荐

0 条评论