在父窗口頁面代碼:

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: {} }, '*')