Skip to content
大纲

乾坤微服务

基本使用

  1. 安装
shell
$ yarn add qiankun # 或者 npm i qiankun -S
  1. 在主应用中注册微应用
js
import { registerMicroApps, start, setDefaultMountApp} from 'qiankun'

  const apps = [ // 子应用配置
    {
      name: 'vueApp',
      entry: '//localhost:10000', // 子应用需要支持跨域
      container: '#vue',
      activeRule: '#/vue',
      props: {test: '8080'}
    },
    {
      name: 'reactApp',
      entry: '//localhost:20000',
      container: '#react',
      activeRule: '#/react'
    },
    {
      name: 'vueAppHash',
      entry: '//localhost:12000',
      container: '#vueHash',
      activeRule: '#/hashhome'
    }
  ]
  // 生命周期
  registerMicroApps(apps, {
    beforeLoad: [
        app => {
            console.log("before load", app);
        }
    ], // 挂载前回调
    beforeMount: [
        app => {
            console.log("before mount", app);
        }
    ], // 挂载后回调
    afterUnmount: [
        app => {
            console.log("after unload", app);
        }
    ] // 卸载后回调
  }) // 注册应用

  // setDefaultMountApp("/vue") // 默认子应用
  start() // 开启
  1. 子应用需要需改打包配置
js
module.exports = {
  publicPath: '/child/vueapp/', // url资源路径
  outputDir: 'appvue', // 打包总出口
  assetsDir: './', // js等资源文件出口
  indexPath: 'index.html', // html文件出口
  devServer: {
    port: 10000,
    headers: {
      'Access-Control-Allow-Origin': '*'
    }
  },
  configureWebpack: {
    output: {
      library: 'vueApp',
      libraryTarget: 'umd'
    }
  }
}
/* react */
module.exports = {
  webpack: (config) => {
    config.output.library = 'reactApp'
    config.output.libraryTarget = 'umd'
    config.output.publicPath = 'http://localhost:20000/'
    return config
  },
  devServer: (configureFunction) => {
    return function (proxy, allowedHsot) {
      const config = configureFunction(proxy, allowedHsot)
      config.headers = {
        'Access-Control-Allow-Origin': '*'
      }
      return config
    }
  }
}
  1. 子应用js更改
js
let instance = null
function render(props) {
  // let store
  if (props) {
    /* ** 方式一 ** */
    Vue.prototype.$actions = props // 将主应用的actions方法拿到,在onGlobalStateChange,可以拿到state的值,等于父传子通讯
    /* ** 方式二 ** */
    console.log(props)
    Vue.prototype.$store = props.store
    Vue.prototype.$mainRouter = props.router
    // store = props.store
  }
  instance = new Vue({
    router,
    // store,
    render: h => h(App)
  }).$mount('#app')
}

// setDefaultMountApp("/vue") // 默认子应用
// start() // 开启

if (window.__POWERED_BY_QIANKUN__) {  // 动态添加publicPath
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}


if (!window.__POWERED_BY_QIANKUN__) { // 默认独立运行
  render();
}

export async function bootstrap(props) {
  
}

export async function mount(props) {
  render(props)
}

export async function unmount(props) {
  instance.$destroy()
}

主应用vue-history或者hash模式

子应用可以是hash或者history

单页面多子应用

需要展示的子应用控制activeRules为true

子应用子路由嵌套可以在一个子组件内引入乾坤

js
import { start, registerMicroApps } from 'qiankun'

  mounted () {
    const apps = [ // 子应用配置
      {
        name: 'vueAppHash',
        entry: '//localhost:12000',
        container: '#vueHash2',
        activeRule: '/child/vueapp/about/hashhome2'
      }
    ]
    registerMicroApps(apps) // 注册应用
    
    if (!window.qiankunStarted2) {
      window.qiankunStarted2 = true;
      start();
    }
  }

应用间通讯

  1. 官方组件通讯,引入initGlobalState,返回MicroAppStateActions,会自动注入微应用mount的props中
js
/* actions.js */
import { initGlobalState } from 'qiankun'

const initState = {}
const actions = initGlobalState(initState)

export default actions
js
/* 在主应用mian.js的注册一次 */
import actions from './utils/actions'
actions.onGlobalStateChange((state) => {
  Vue.prototype.globalData = state 
})
actions.setGlobalState({ // 第一次赋值
  data1: 'initData1',
  data2: 'initData2'
})
js
/* 在子应用mian.js,从props内拿到传过来的信息 */
function render(props) {
  // let store
  if (props) {
    /* ** 方式一 ** */
    Vue.prototype.$actions = props // 将主应用的actions方法拿到,在onGlobalStateChange,可以拿到state的值,等于父传子通讯
  }
  instance = new Vue({
    router,
    // store,
    render: h => h(App)
  }).$mount('#app')
}
js
/* 子应用需要用到的组件 */
this.$actions.onGlobalStateChange(state => { // 组件创建时会触发,将父组件传进来的值附上。
  console.log(state, '微应用helloworld')
  this.data1 = state.data1
  this.data2 = state.data2
}, true)

/* 修改数据 */
change() {
  this.$actions.setGlobalState({data1: '子应用Data'})
}
  1. vuex方式
js
/* 主应用传入store */
 {
  name: 'vueApp',
  entry: '//localhost:10000/child/vueapp/', // 子应用需要支持跨域
  container: '#vue',
  activeRule: '/child/vueapp',
  // activeRule: () => true,
  props: {
    store,
    router
  }
},
js
/* 子应用mian.js拿到 */
function render(props) {
  if (props) {
    Vue.prototype.$storeMian = props.store
    Vue.prototype.$mainRouter = props.router
  }
  instance = new Vue({
    router,
    render: h => h(App)
  }).$mount('#app')
}
js
/* 组件拿到 */
this.mainData = this.$storeMian.state.info

changeStoreData () {
  this.mainData = 'newStoreData-子应用' // 自身修改,因为$storeMian修改不触发视图更新
  this.$storeMian.commit('updataInfo','newStoreData-子应用');
},

子应用跳转其他应用

传入父组件router作为props,然后子应用拿到做跳转

Released under the MIT License.