基于Vue2 & qiankun的微前端实现(第2章-数据通信、方法共享)

1,613 阅读1分钟

引子

image.png

相较于iframe,微前端解决了应用间通信困难的痛点,这章就聊聊我们在实际开发中是如何实现通信和共享的。

数据通信

我直接把整个vuex传过去!

image.png

注册子应用时把vuex放在props里传过去:

import store from '@/store'

registerMicroApps([
  {
    name: 'react app', 
    entry: '//localhost:7100',
    container: '#yourContainer',
    activeRule: '/yourActiveRule',
    props: {
        store // 传递vuex
    }
  }
])

子应用在初始化钩子里用Vue.observable()把主应用的vuex挂在自己的Vue原型上:

export async function bootstrap (props = {}) {
  // 主应用传递的 store 挂载原型上,添加响应
  Vue.prototype.$mainStore = Vue.observable(props.store)
  ……
}

在子应用里使用主应用的vuex,实现数据通信和共享:

computed: {
    //响应式变化,数据共享
    langInMainApp(){
        return this.$mainStore.state.lang
    }
}
methdos:{
    //子应用改变主应用中的状态,数据通信
    updateLangInMainApp(lang){
        //UPDATE_LANG对应的mutation需要在主应用里实现
        this.$mainStore.commit('UPDATE_LANG',lang)
    }
}

方法共享

在注册子应用除了传递vuex实现数据的通信,还可以传递一些关键方法:

import getSomething from '@/utils'
import store from '@/store'

registerMicroApps([
  {
    name: 'react app', 
    entry: '//localhost:7100',
    container: '#yourContainer',
    activeRule: '/yourActiveRule',
    props: {
        store, // 传递vuex
        func: {
            getSomething //传递方法
        }
    }
  }
])

相似的,子应用在初始化钩子里用把主应用的方法挂在自己的Vue原型上:

export async function bootstrap (props = {}) {
  Vue.prototype.$mainFunc = props.func
  ……
}

在子应用里使用主应用的方法:

import getSomething from '@/utils'
methdos:{
    getSomething(){
        let func = window.__POWERED_BY_QIANKUN__ ? this.$mainFunc.getSomething : getSomething
        return func()
    }
}

实际应用

通过替换请求方法管控权限

主应用封装request方法,包含权限相关的处理。所有的请求都需要调用这个方法发起:

import request from '@/utils/request'

export function getServerConfig () {
  return request({
    url: '/sys-system/serverConfig',
    method: 'get'
  })
}

由于微前端本身并不能拦截子应用发起的请求,需要侵入式的替换掉子应用内部使用的request。在注册子应用时传入主应用的reuqest方法并修改子应用抛出自己的request方法的逻辑:

//origin
const request = axios.create({……})
export default request
//after
const requestOwn = axios.create({……})
const request = window.__POWERED_BY_QIANKUN__ ? Vue.prototype.$mainFunc.request : requestOwn
export default request