前端微应用框架(qiankun)调研

一、安装

1、主应用安装qiankun(子应用只做代码配置,无需任何安装)

yarn add qiankun # 或者 npm i qiankun -S

 

二、关键参数介绍

1、主应用注册微应用

import { registerMicroApps, start, setDefaultMountApp,  loadMicroApp  } from 'qiankun';

registerMicroApps(apps, lifeCycles?) 是qiankun框架的一个方法,用于注册微前端应用,apps树数组,元素是对象,每个元素即为一个子应用的注册信息,lifeCycles是生命周期钩子
//apps元素属性介绍

name: 必选项,当前应用的名称,也就是微应用的名称。
entry: 必选项,微应用的入口,可以是URL链接,也可以是一个fetch函数,用于获取应用静态资源。
container: 必选项,微应用渲染的节点,也就是挂载点。
activeRule: 必选项,激活微应用的规则,可以是字符串、函数或者Array。如地址路径。
props: 非必选项,主应用传递给微应用的数据,也就是传递的参数。
loader: 自定义的加载函数,可以用来监听微应用的加载情况。
rewriteRule: Optional<Function> 当不需要微应用隔离(常见于微应用为同域的legacy系统、无法修改window路由等打开方式)时,可以借助此函数路由重写,规避 qiankun 改写 url 导致的路由处理问题。
singular: 非必选项,是否单例模式,默认为 true。
sandbox: 非必选项,为微应用配置沙箱。
mountElementId: 非必选项,确定唯一的 DOM 容器节点 id。
getTemplate: 非必选项,getTemplate 方法将在 initial 阶段调用,可用于改写 template。
render: 非必选项,更自由的 render 方法,用于自定义渲染行为。
history: 非必选项,设置微应用的 history 模式,可选browser、hash和memory。
lifeCycles: 指定微应用的生命周期钩子函数,包括 onload、onmount、onunmount。/

//lifeCycles介绍
  • beforeLoad: 可选项,微应用加载前的生命周期钩子,Promise。
  • beforeMount: 可选项,微应用装载前的生命周期钩子,Promise。
  • afterMount: 可选项,微应用装载后的生命周期钩子,Promise。
  • beforeUnmount: 可选项,微应用卸载前的生命周期钩子,Promise。
  • afterUnmount: 可选项,微应用卸载后的生命周期钩子,Promise。

start()启用qiankun

在js文件中可通过回调验证启用是否成功

// 启动qiankun
start().then(() => {
  console.log('qiankun启动成功');
}).catch(err => {
  console.error('qiankun启动失败', err);
});

setDefaultMountApp设置主应用启动后立即进入的微应用

import { setDefaultMountApp } from 'qiankun';
//入参为子应用的激活路由
setDefaultMountApp('/homeApp');

loadMicroApp  手动加载微应用,无需在registerMicroApps中注册

它可以在任何时候任何地方加载一个微应用。如果你需要在特定的时机启动并加载剩余的微应用
说明:不需要激活路由,loadMicroApp执行后会在当前路由立即加载子服务
// 导入loadMicroApp方法
import { loadMicroApp } from 'qiankun'

// 当你需要使用reactChild的时候,开始加载和启动它
const app = loadMicroApp(
  {
    name: 'reactChild', 
    entry: '//localhost:1111', 
    container: '#reactChild', 
  }
);

// 当你不再需要这个应用的时候,可以卸载它
app.unmount();

   

二、项目配置

1、主应用配置

main.js引入qiankun,注册子应用

import { registerMicroApps, start } from 'qiankun';
/ 微应用的信息
const apps = [
  {
    name: 'vueChild', //应用的名字
    entry: '//10.3.124.216:10200', // 应用的入口,即子应用的访问地址
    container: '#vueChild', // 容器名
    activeRule: '/vue-child', //激活的路径,即但URL成http://xxxx:'端口'/vue-child/#/时,触发加载子应用
  },
];
// 注册微应用 registerMicroApps第二个参数配置钩子函数
registerMicroApps(apps,{
  beforeLoad: [
    app => {
      console.log('beforeLoad')
      console.log(app)
    },
  ],
  beforeMount: [
    app => {
      console.log('beforeMount')
   },
  ],
  afterUnmount: [
    app => {
      console.log('afterUnmount')
    },
  ],
}); 

// 启动qiankun,也可传参,参考qiankun1——参数介绍
start()

2、设置子应用的容器

即在主应用页面提供一个插入子应用的dom节点,节点id与注册时的container值相同

<div id="app">
  <nav>
    <router-link to="/home" @click="type = ''">Home</router-link> |
    <router-link to="/vue-child/" @click="type = 'vue-child'">About</router-link>
  </nav>
  <!-- 子应用容器,子应用挂载之前要有,不然挂载失败。id值要与注册时属性container的值相同-->
  <div id="vueChild"></div>
  <!--    页面视口,用于显示主应用的内容,跟子应用没关系-->
  <router-view ></router-view>
</div>

3、子应用配置

1、在src 目录新增public-path.js
if (window.__POWERED_BY_QIANKUN__) {  
    __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}


2、main.js引入public-path.js


3、配置main.js
let instance = null
function render(props = {}) {
  const { container } = props
  instance = new Vue({
    router,
    store,
    render: h => h(App)
  }).$mount(container ? container.querySelector('#app') : '#app')//为了避免根 id 
#app 与其他的 DOM 冲突,需要限制查找范围。
}// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
  render()
}

export async function bootstrap() {
  console.log('vue app bootstraped')
}
export async function mount(props) {
  render(props)
}
export async function unmount() {
  instance.$destroy()
  instance.$el.innerHTML = ''
  instance = null
}

4、修改webpack的打包配置
//1、处理跨域
devServer: {
  // 监听端口
  port: 10200,
  // 配置跨域请求头,解决开发环境的跨域问题
  headers: {
    "Access-Control-Allow-Origin": "*",
  },
},
chainWebpack: (config) => {
    //配置打包
  config.output.library('vueChild').libraryTarget('umd')
},

  

三、子父应用通信

1、初始加载时通信
//主应用
//注册子应用时,参数通过props传递,可传递参数和回调函数
const apps = [
  {
    name: 'vueChild', //应用的名字
    entry: '//localhost:10200', // 应用的入口
    container: '#vueChild', // 容器名
    activeRule: '/vue-child', //激活的路径,即但URL成http://xxxx:'端口'/vue-child/#/时,触发加载子应用
    props: {
      message: 'Hello from main app!',
      callback: (data) => {
        console.log('Data received from subApp-1:', data);
      },
    },
  },
  
  //子应用
  //在钩子函数中接收
  export async function mount(props) {
      console.log('child',props)
      render(props)
      props.callback('Hello from subApp-1.');
  }

2、加载后的自定义事件传参

//使用浏览器的CustomEvent、dispatchEvent、addEventListener API进行监听
// 主应用
window.addEventListener('subAppEvent', (event) => {
  console.log('Received event from subApp:', event.detail);
});

// 子应用
const event = new CustomEvent('subAppEvent', { detail: 'Hello from subApp!' });
window.dispatchEvent(event);

3、卸载时传参

使用自定义传参方式将参数从子组件传递给父组件,只需在相应的应用钩子中触发。
4、子应用与子应用间通信
 
//1、基于事件的方式进行通信
// 子应用A发送事件
window.dispatchEvent(new CustomEvent('eventName', { detail: 'payload' }))

// 子应用B监听事件
window.addEventListener('eventName', (event) => { console.log(event.detail) })


//2、利用全局变量/函数方式进行通信
//在主应用中定义全局的变量或者函数作为 "通信管道",然后在子应用中调用这些全局的变量或者函数来进行通信
// 主应用
window.globalVar = { /* 全局变量 */ }
window.globalFunc = function() { /* 全局函数 */ }

// 子应用
console.log(window.globalVar)
window.globalFunc()

//3、使用Redux、Vuex状态管理库
//4、使用缓存如:localStorage

  

 

 

 

posted @ 2023-09-04 20:06  web-慰尘  阅读(1882)  评论(0编辑  收藏  举报