在父窗口页面代码:
1 <template> 2 <el-dialog 3 title="" 4 :visible.sync="visible" 5 width="30%" 6 class="ifr-dialog" 7 center 8 @opened="handleOpened"> 9 <div> 10 <iframe :src="src" ref="iframe"></iframe> 11 </div> 12 </el-dialog> 13 </template> 14 15 <script> 16 export default { 17 name: 'IframeDialog', 18 props: { 19 visible: { 20 type: Boolean, 21 default: false 22 }, 23 src: { 24 type: String, 25 default: '' 26 } 27 }, 28 data() { 29 return { 30 iframeWin: {} 31 }; 32 }, 33 methods: { 34 handleOpened() { 35 this.iframeWin = this.$refs.iframe.contentWindow; 36 }, 37 handleMessage (event) { 38 // 根据上面制定的结构来解析iframe内部发回来的数据 39 const data = event.data; 40 console.log(data); 41 } 42 }, 43 mounted () { 44 // 在外部vue的window上添加postMessage的监听,并且绑定处理函数handleMessage 45 window.addEventListener('message', this.handleMessage); 46 } 47 } 48 </script>
在iframe页面:
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="utf-8"> <title></title> </head> <body> <div class="container" style="margin: 150px auto;text-align: center"> Hello, world! <div style="margin: 15px auto;font-size: 16px;color:#6c757d">当前窗口将在<span id="spNumber" class="text-warning">5</span>秒后自动关闭!</div> </div> </body> <script> function autoCloseWindow() { var closeIntv = setInterval(function () { var num = parseInt(document.getElementById('spNumber').innerText, 10); if (!num) { // 向父vue页面发送信息 clearInterval(closeIntv); window.parent.postMessage({ cmd: 'testCmd', params: { msg: 'iframe test' } }, '*'); } else { document.getElementById('spNumber').innerText = num - 1; } }, 1000); } autoCloseWindow(); </script> </html>
这里需要注意的是:
1、在vue中是通过给iframe组件添加ref值来注册引用信息,引用指向的就是DOM元素,注册之后就可以通过$refs来查到对应的DOM元素对象了。
2、只有当元素渲染出来之后,在$refs中才能看到对应的DOM元素,所以我把下面这句话放在对话框打开之后执行,而不是放在mount方法里执行。
this.iframeWin = this.$refs.iframe.contentWindow;
3、需要注册监听事件:
window.addEventListener('message', this.handleMessage);
4、给对象推送消息:
// 向父vue页面发送信息
window.parent.postMessage({
cmd: 'testA',
params: {
success: true,
data: {}
}
}, '*');
// 外部vue向iframe内部传数据
this.iframeWin.postMessage({
cmd: 'testB',
params: {}
}, '*')