前端微服务 - ifram 解决方案
介绍
作为 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 的来源 source 和 url 的值 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
}