vue項目iframe的傳值問題

  • 2019 年 11 月 21 日
  • 筆記

前言

項目需要,我需要引入一個已經封裝好的瀏覽器插件。插件只能以html的方式調用,

  所以。我把插件的使用封裝了一個html頁面。vue項目則利用iframe的方式引入。

  到這裡我就遇到了一個問題,那就是vue項目中iframe的傳值問題,這裡做個筆記防止之後忘記,

  如果有其他的方式,歡迎大家交流,不勝感激。

正文

  先寫幾個簡易的demo

需要用到的html

<!DOCTYPE html>  <html lang="en" style="height: 100%;">    <head>    <meta charset="utf-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width,initial-scale=1.0">    <link rel="icon" href="<%= BASE_URL %>favicon.ico">    <title>測試damo</title>  </head>    <body>    <noscript>      <strong>請使用支援javascript的瀏覽器</strong>    </noscript>    <div id="app">1213123111220980980</div>    <button onclick="setData()">列印本地的值</button>    <button onclick="getData()">點擊獲取值vue的值</button>  </body>  <script>    var wpsData;      var aaaaa = '22222'    function setData(){      alert(aaaaa)    }      function getData(){      alert(wpsData)    }    </script>    </html>

父級頁面用iframe調用html

<template>    <div>      <div>在線文檔編譯組件</div>      <el-button @click="getData()">點擊獲取iframe數據</el-button>      <el-button @click="setData('我是vue數據')">向iframe中發送數據</el-button>      <iframe id="mainIframe" ref="mainIframe" name="mainIframe" src="./test.html" frameborder="0" scrolling="auto" @load="loaded" />    </div>  </template>  <script>  export default {    name: 'wps-edit',    props: { },    mounted() {    },    methods: {      getData() {      },      setData(data) {      }    }  }  </script>  <style lang="scss" scoped></style>

這裡提供兩種傳值方式:

第一種:postMessage

 1、父頁面生命周期函數中
const mapFrame = this.$refs['mainIframe']      if (mapFrame.attachEvent) { // 兼容瀏覽器判斷        mapFrame.attachEvent('onload', function() {          const iframeWin = mapFrame.contentWindow          iframeWin.postMessage('初始化值', '*')          // data傳遞的參數   *寫成子頁面的域名或者是ip        })      } else {        mapFrame.onload = function() {          const iframeWin = mapFrame.contentWindow          iframeWin.postMessage('初始化值', '*')        }      }
2、html頁面接受數據
window.addEventListener('message', function(messageEvent) {          var data = messageEvent.data;          console.log('收到vue的數據:',data);          wpsData = data          console.log('wpsData:',wpsData);      }, false);

在頁面載入結束,你就能發現html頁面中的wpsData值已經被改變成了父級頁面傳過來的值。

這種方式是載入一次,數據不能實時同步,或者我沒有實時同步數據的方法

 第二種:直接操作iframe

1、父級頁面直接給iframe的window對象設置值
setData(data) {        const obj1 = window.frames['mainIframe']// 獲得對應iframe的window對象        obj1.wpsData = '設置的數據'      }
2、父級頁面設置完值後,在html頁面直接列印對應的參數,此時會發現wpsData數據已經改變
function getData(){      alert(wpsData)    }

這種方式每次在父級頁面改變值,html頁面就會實時更新數據,我暫時用的這種方式,至於有什麼bug,我正在研究。

完整的頁面程式碼

html頁面

<!DOCTYPE html>  <html lang="en" style="height: 100%;">    <head>    <meta charset="utf-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width,initial-scale=1.0">    <link rel="icon" href="<%= BASE_URL %>favicon.ico">    <title>測試damo</title>  </head>    <body>    <noscript>      <strong>請使用支援javascript的瀏覽器</strong>    </noscript>    <div id="app">1213123111220980980</div>    <button onclick="setData()">列印本地的值</button>    <button onclick="getData()">點擊獲取值vue的值</button>  </body>  <script>    var wpsData;    window.addEventListener('message', function(messageEvent) {          var data = messageEvent.data;          console.log('收到vue的數據:',data);          wpsData = data          console.log('wpsData:',wpsData);var aaaaa = '22222'    function setData(){      alert(aaaaa)    }    function getData(){      alert(wpsData)    }    </script>    </html>

父級頁面

<template>    <div>      <div>在線文檔編譯組件</div>      <el-button @click="getData()">點擊獲取iframe數據</el-button>      <el-button @click="setData('我是vue數據')">向iframe中發送數據</el-button>      <iframe id="mainIframe" ref="mainIframe" name="mainIframe" src="./test.html" frameborder="0" scrolling="auto" @load="loaded" />    </div>  </template>  <script>  // 工具類  export default {    name: 'wps-edit',    props: {    },    mounted() {      const mapFrame = this.$refs['mainIframe']      if (mapFrame.attachEvent) { // 兼容瀏覽器判斷        mapFrame.attachEvent('onload', function() {          const iframeWin = mapFrame.contentWindow          iframeWin.postMessage('初始化值', '*')          // data傳遞的參數   *寫成子頁面的域名或者是ip        })      } else {        mapFrame.onload = function() {          const iframeWin = mapFrame.contentWindow          iframeWin.postMessage('初始化值', '*')        }      }    },    methods: {      loaded() {        const vm = this.$refs.mainIframe.contentWindow.vm        console.log(vm)        // vm.func1()      },      getData() {        const obj1 = window.frames['mainIframe']// 獲得對應iframe的window對象        alert(obj1.aaaaa)      },      getWpsData() {        return 'wps數據'      },      setData(data) {        const obj1 = window.frames['mainIframe']// 獲得對應iframe的window對象        obj1.wpsData = '設置的數據'      }    }  }  </script>  <style lang="scss" scoped></style>

結尾

學無止境,還是有很多不知道的,繼續精進技術。。。

  歡迎大家溝通交流。