vue3.0+乾坤实现微应用

首先是引入乾坤

npm i qiankun -S

在main.js中,引入乾坤

import { registerMicroApps,runAfterFirstMounted,addGlobalUncaughtErrorHandler } from 'qiankun';

注册

registerMicroApps( {
      name: 'son',
      entry: 'http://localhost:8001/',
      container: '#sonList', // 微应用挂载节点 - 微应用加载完成后将挂载在该节点上
      activeRule:'son',
      // activeRule: getActiveRule('son'),
      // props: {
      //   msg: {
      //     data: {
      //       mt: 'hello,我是来自父亲的关怀!'
      //     }
      //   },
      //   fn: {
      //     show(msg) {
      //       console.log('one:', msg)
      //     }
      //   }
      //   // routerBase: '/sub-vue' // 下发路由给子应用,子应用根据该值去定义qiankun环境下的路由
      // }
    }, {
  beforeLoad: app => {
    console.log('before load app.name====>>>>>', app.name)
    return Promise.resolve();
  },
  beforeMount: [
    app => {
      console.log("dddddd");
      console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);
    },
  ],
  afterMount: [
    app => {
      console.log('[LifeCycle] after mount %c%s', 'color: green;', app.name);
      return Promise.resolve();
    }
  ],
  afterUnmount: [
    app => {
      console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name);
    },
  ],
})

判断是否调用成功和异常处理

runAfterFirstMounted(() => {
  console.log('第一个子应用加载完毕后的回调')
})
/**
 * 添加全局的未捕获异常处理器
 */
 addGlobalUncaughtErrorHandler((event) => {
  const { message: msg } = event;
  // 加载失败时提示
  if (msg && msg.includes("died in status LOADING_SOURCE_CODE")) {
   console.log("微应用加载失败,请检查应用是否可运行___"+msg);
  }
});
runAfterFirstMounted(() => {
  console.log('第一个子应用加载完毕后的回调')
})
/**
 * 添加全局的未捕获异常处理器
 */
 addGlobalUncaughtErrorHandler((event) => {
  const { message: msg } = event;
  // 加载失败时提示
  if (msg && msg.includes("died in status LOADING_SOURCE_CODE")) {
   console.log("微应用加载失败,请检查应用是否可运行___"+msg);
  }
});

然后在显示的vue中,在哪里使用就在哪里打开,当然,也可以放到main.js全局开启乾坤

<template>
  <div id="sonLit"></div>
</template>

<script >
import { onMounted } from 'vue'
import { start } from "qiankun";
export default {
  setup() {
    onMounted(() => {
      if (!window.qiankunStarted) {
        window.qiankunStarted = true;
        start({
            prefetch: true, // 开启预加载
          sandbox: {
            strictStyleIsolation: true,
            experimentalStyleIsolation: true,
          },
        });
      }
    });
  },
};
</script>

在子应用中,添加public-path.js

/* eslint-disable */
if (window.__POWERED_BY_QIANKUN__) {
    __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
  }
  /* eslint-disable */

然后引入 import './public-path'

修改router,直接export default routes,将注册放到main.js中

import { createRouter, createWebHistory } from 'vue-router';
let router = null;
let instance = null;
let history = null;
 function render(props = {}) {
    const { container } = props;
    console.log("props.name",props.name);
    history = createWebHistory(window.__POWERED_BY_QIANKUN__ ? `${props.name}` : '/');
    router = createRouter({
      history,
      routes,
    });
 instance = createApp(App);
    instance.use(router);
    instance.use(store);
instance.mount(container ? container.querySelector('#app') : '#app');
  }

// 本地调试
  if (!window.__POWERED_BY_QIANKUN__) {
    render()
  }


  // 生命周期 - 挂载前,在这里由主应用传过来的参数
export async function bootstrap() {
 
      // console.log('one bootstrap'+JSON.stringify(props))
    console.log( localStorage.getItem('test'));
    
  }
  
  // 生命周期 - 挂载后
  export async function mount(props) {
   
    render(props)

      //console.log(props.msg.data);
      
    // // 主应用传递过来的 props.fn 是一个对象。循环遍历下,将各个属性绑定到子应用的原型链上
    // Object.keys(props.fn).forEach(method => {
    //     createApp.prototype[`$${method}`] = props.fn[method]
    // })
    // 渲染
  
  }
  
  // 生命周期 - 解除挂载
  export async function unmount() {
    instance.unmount();
    instance._container.innerHTML = '';
    instance = null;
    router = null;
    history.destroy();
    // instance=instance.unmount(props);
    // instance._container.innerHTML = "";
    // instance = null;
    // router = null
  }

在vue.config.js中

const { name } = require('./package.json')
const port = 8001

module.exports = {
  devServer: {
    port,
    // 允许被主应用跨域fetch请求到
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Authorization': '0b72a02adf334844a0367e021ad1c25c'
    }, proxy: {
      '/omg': {
        target: 'http://127.0.0.1',
        changeOrigin: true,
        ws: true,
        pathRewrite: { '^/omg': '' }
      }
    }
  },
  configureWebpack: {
    output: {
      library: `${name}-[name]`,
      // 把子应用打包成umd库格式
      // 当我们把 libraryTarget 设置为 umd 后,我们的 library 就暴露为所有的模块定义下都可运行的方式了,主应用就可以获取到微应用的生命周期钩子函数了
      libraryTarget: 'umd',
      jsonpFunction: `webpackJsonp_${name}`
    }
  }
}

 

posted @ 2021-12-18 16:20  龙丶谈笑风声  阅读(2589)  评论(0编辑  收藏  举报