如何在 Vuejs 模板中使用带有 iframe 的 MessageChannel

问题描述 投票:0回答:0

我们需要在 iframe 中显示来自外部站点的数据,同时还能够监听事件。

我可以使用从 API 返回的 url 来渲染 iframe。卡住的地方是事件处理程序和消息传递。

具体来说:

  1. 我应该在数据中定义通道吗?或者作为计算属性?有关系吗?
  2. 在 iframe 元素的回调中发送“port2 到 iframe”的代码片段——我如何在我的 vue 模板中引用这个回调?
  3. 我如何实际使用 channel.port1.onmessage 片段?我假设这是在监听从端口 2 中的 iframe 发送的任何消息。这是我根据显示的 event.data.handlerName 调用不同函数的地方吗?

这里是API文档:

Use the MessageChannel API to create a new channel. You’ll use the two ports connected to the channel to communicate between your application and the UX inside the iframe.

const channel = new MessageChannel();

Send port2 into the iframe embedding the UX using the onLoad callback of the <iframe> element:

iframe.addEventHandler(“load”, (event) => {
    iframe.contentWindow.postMessage("", "*", [channel.port2]);
});

Now that the embedded experience has received port2, listen to events from the iframe on port1, the port you retained earlier:

channel.port1.onmessage = (event) => {
    // check event.data.handlerName and event.data.eventType,
    // and handle messages sent from the embedded UX
};

这是我的模板。

<template>
  <div class="dashboard">
    <div class="dashboard__container">
      <div class="dashboard__container--header">
        <h1>Contractors</h1>
      </div>
      <div class="dashboard__container--body">
        <iframe 
          :src="iframaData"
          id="frame"
          ></iframe>
      </div>
    </div>
  </div>
</template>


<script>
import { mapState } from 'vuex'
import firebase from 'firebase/app';

export default {
  name: 'accountPayroll',
  data: () => ({ 
    iframaData: null,
    channel: '',
  }),
  methods: {
    createComponentSession() {
      console.log('fetching')
      const createComponentSession = firebase.functions().httpsCallable('createComponentSession')
      createComponentSession({
        id: this.currentUser.uid
      })
      .then(result => {
        if (result && result.data && result.data.url) {
          this.iframaData = result.data.url
          console.log(result.data)
        }
      })
    },
    sendPort2() {
      this.iframe.addEventHandler(event => {
        this.iframe.contentWindow.postMessage("", "*", [this.channel.port2]);
      });
    },
    message() {
      this.channel.port1.onmessage = (event) => {
        // return event.data.handlerName == "ONBOARDING"
        console.log(event)
      };
    }
  },
  computed: {
    ...mapState(['currentUser', 'userProfile']),
    channel1() {
      return this.channel.port1;
    },
    channel2() {
      return this.channel.port2;
    },
    iframe() {
      return this.$el.querySelector("iframe")
    }
  },
  created() {
    this.channel = new MessageChannel()
    this.createComponentSession()
  },
  mounted() {
    this.sendPort2()
    this.message()
  },
  beforeDestroy () {
    this.iframaData = null;
    delete this.iframeData;
  }
}

</script>

任何帮助将不胜感激。谢谢!

vue.js rest iframe message-channel
© www.soinside.com 2019 - 2024. All rights reserved.