首頁 > 軟體

vue元件和iframe頁面的相互傳參問題及解決

2022-05-31 18:00:10

vue元件和iframe頁面相互傳參

目前網上大多關於iframe父子傳參的部落格都是在敘述父頁面是html檔案,子iframe檔案也是html檔案,涉及到父頁面是vue元件子iframe頁面是html的部落格多數講的不是很明白;

而最近我在專案中碰到了這種需求:在vue元件中嵌入iframe頁面,並實現父子傳參;

vue元件呼叫iframe頁面方法和引數

下面是在 vue元件中(父元件) 一個通過點選按鈕觸發的方法:

 sentToIframe() {
      let childFrameObj = document.getElementById("unityiframe");
      console.log("childFrameObj", childFrameObj);
      // childFrameObj.contentWindow.getMessageFromParent(this.tData); //第一種向子iFrame傳參方式,呼叫iframe的methods達到傳參的目的
      this.$refs.unity.contentWindow.getMessageFromParent(this.tData); // 這樣也是可以呼叫子iframe的方法
      // childFrameObj.contentWindow.frameData = "這是vue元件給你的引數!" // 傳參成功
      this.$refs.unity.contentWindow.frameData =
        "這是vue元件給你的第二個引數!"; //傳參成功
      console.log("傳送完成");
      //此外,還可以通過DOM操作,操作子iframe的DOM
      var t = document
        .getElementById("unityiframe")
        .contentWindow.document.getElementById("dd");
      console.log(t);
      //
      console.log("frameData?", unityiframe.window.frameData); //利用id可以呼叫到iframe裡的變數
      // console.log("frameData?",this.$refs.unity.window.frameData) //利用ref呼叫不到iframe裡的變數
    },

子元件 iframe頁面 中有一個被呼叫的方法及變數:

  var frameData = "別喊我!" //此變數用於測試 vue元件是否能呼叫此變數
  function getMessageFromParent(value){
    // 接受從vue元件中傳過來的引數
    console.log(`我接收到parent傳過來的引數了:${value}`)
  }

點選按鈕的結果是:

iframe頁面向vue元件傳參

vue元件中有一個供iframe頁面呼叫的方法:

    getFromIframe(value) {
      console.log(`我是iframe傳過來的引數:${value}`);
      console.log("我被iframe呼叫了!");
      console.log(this.vueData);
      console.log(`改變前是:你是否能夠改變我;改變後是:${this.isChangeMe}`);
    }

iframe呼叫vue元件方法的程式碼:

  function Obj(res){
  // Obj通過按鈕點選觸發
    console.log(parent)
        // 呼叫vue元件方法
      parent.getFromIframe("我叫iframe")
      // 向vue元件傳送引數 && 改變vue元件的引數
      parent.isChangeMe = "你已經被我iframe改變了"
  }

但是 !!!!!!!!!!!!!!!

只這麼做是不夠的,會報錯,如下:

個人猜想: 問題的原因是 iframe的parent並不是vue範例!

目前只找到了一個辦法來解決這個問題:

就是在created勾點裡加上這兩句,

  created() {
    window.getFromIframe = this.getFromIframe; //把vue範例中的方法參照給window物件
  },

在呼叫的vue範例的方法中 加上對vue內變數的改變

    getFromIframe(value) {
      console.log(`我是iframe傳過來的引數:${value}`);
      console.log("我被iframe呼叫了!");
      console.log(this.vueData);
      this.isChangeMe = window.isChangeMe;// 把window變數 賦值給 vue 範例變數;使得在iframe中能夠改變vue範例中變數
      console.log(`改變前是:你是否能夠改變我;改變後是:${this.isChangeMe}`);
    }

最終的執行結果是:

bingo!!!!! 問題暫時得到了解決。

小結一下:vue元件iframe 的嵌入麻煩多多,且目前還沒還沒找到正統的方法;此外,還有很多坑我還沒踩到,如果後續這方面有什麼問題 以及 其他的解決方案,我會繼續更新到這上面來的!

內嵌iframe頁面並進行傳值

需求是把兩個單獨的系統在一個總的系統作為選單進行免密登入,由於時間還有跨域和不同的token等問題,就使用了內嵌iframe,因為是不同的域名進入子系統也要本地儲存一下(獲取的user資訊以及token傳入到iframe子系統)

<template>
  <div class="hello">
    <div>
      <iframe src="http://xxxxxxxxxxxxxx" frameborder="0"  id="myIframe" ref="myIframe"></iframe>
    </div>
  </div>
</template>
export default {
  mounted() {
    this.iframeWin = this.$refs.myIframe.contentWindow;
    //最開始做的是點選事件是沒有問題的  後面需要自動傳值就不行  也試了模擬點選還是不行
    //原因是iframe還沒載入完  所以使用onload
    document.getElementById("myIframe").onload=function(){
      this.fatherpost()
    };
  }
  methods:{
    fatherpost(e){//iframe傳值
         this.iframeWin.postMessage({
             params:{
               data:data//傳的資料
             }
         },'http://xxxxxxxxxxxxxx')
    },
  }
}
//iframe接收
export default {
  mounted() {
     window.addEventListener('message',function(e){
       console.log(e.data)
     },false)
  }
}
//子傳父的話   掛載和接收的方式都是差不多
window.parent.postMessage(message, targetOrigin, [transfer])

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com