前端微服务 - ifram 解决方案

BACK 2021-10-28 10-20-00
  • 前端微服务
  • iframe

介绍

作为 html 提供 iframe 也可以作为前端微服务的解决方案,也是最简单的方案之一。配置过程中只需要通过 window.addEventListener('message', fn(), false)postMessage 两个方法,使父级子级进行数据通讯,从而达到数据共享的功能。

1、主项目配置

views/projects 目录下新建一个 .vue 文件,代码如下:

<template>
  <div v-loading="showLading"
    element-loading-text="子项目模块加载中">
    <iframe
      ref="monitor"
      width="100%" height="100%"
      v-if="src"
      @load="postMsg"
      :src="src">
    </iframe>
  </div>
</template>

<script>
export default {
  name: 'microApp',
  components: {
  },
  data() {
    return {
      showLading: true,
      src: ''
    }
  },
  created() {
    // microApps 为全局引入
    this.src = microApps.microApp
  },
  mounted() {
    // 监听 iframe 上传信息
    window.addEventListener('message', this.getMsg, false)
  },
  methods: {
    // 下传数据
    postMsg() {
      this.showLading = false
      let _placeInfo = JSON.parse(sessionStorage.getItem('placeInfo'))
      this.$refs.monitor.contentWindow.postMessage({
        placeInfo: _placeInfo,
        axiosurls
      }, this.src)
    },
    // 获取消息
    getMsg (event) {
      let eventData = event.data
      console.log('iframe 基站接收到的消息:', eventData)
      // todo something
    }
  },
  beforeDestroy() {
    // 清除监听事件
    window.removeEventListener('message', this.getMsg, false)
  }
}
</script>
<style scoped lang="stylus" rel="stylesheet/stylus">
</style>

2、子项目修改

接下来只需要在 app.vue 通过 window.addEventListener('message', this.receiveMsg, true) 方法监听到父级下传的信息,接收到信息后可以对信息进行保存或修改。

如获取到登录信息后,对登录信息进行保存,就可以实现登录共享了。

2.1、判断是否是套用 iframe

if(window.top === window.self) {
    console.log('不在iframe中')
} else {
    console.log('在iframe中')
    // 可以标识一下是从 iframe 引入的
    this.IFRAME_INFO.IS_IFRAME = true
}

2.2、监听消息获取

在生命周期的 mounted() 添加监听代码

// 从父级获取缓存
this.$nextTick(() => {
    window.addEventListener('message', this.receiveMsg, true)
})

methods: 添加获取方法的函数

receiveMsg(event) {
    // todo something
}

2.3、向父级项目上传消息

如果当遇到子项目退出登录信息时,需要将已登录的信息通知到父级项目,从而使父级项目也退出登录信息。

首先先拿到 iframe 的来源 sourceurl 的值 origin

receiveMsg(event) {
    if(event.data.placeInfo) {
        // 暂存 iframe 的来源
        this.IFRAME_INFO.TRAGET = event.source
        // 暂存 iframe 的url地址
        this.IFRAME_INFO.ORIGIN = event.origin
    }
}

然后通过 postMessage 上传数据状态

// 如果是从iframe引入,需要往上传数据状态
if (this.IFRAME_INFO.IS_IFRAME) {
    this.IFRAME_INFO.TRAGET.postMessage({placeInfo: ''}, this.IFRAME_INFO.ORIGIN)
}

2.4、向父级项目接收子级项目上传消息

在父级项目下对应 .vue 页面的 mounted() 去监听上传消息

// 监听 iframe 上传消息
window.addEventListener('message', this.getMsg, false)

methods: 添加接收消息的函数

// 获取消息
getMsg (event) {
    let eventData = event.data
    console.log('iframe 基站接收到的消息:', eventData)
    // todo something
}
Copyright © 2016-2024 Nuxt - MIT License