Vue下iframe如何实现和父窗口的通信

在父窗口页面代码:

 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>
View Code

在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: {}
      }, '*')
 
posted @ 2020-04-30 23:30  linyujade  阅读(1183)  评论(0编辑  收藏  举报