qiankun官方文档:qiankun - qiankun
一、创建主应用:
这里以 vue 为主应用,vue版本:2.x
// 全局安装vue脚手架
npm install -g @vue/cli
vue create main-app
省略 vue 创建项目过程,若不会可以自行百度查阅教程
二、到 主应用(main-app)目录下,安装微前端框架依赖 qiankun:
npm i qiankun -S
三、改造主应用(main-app):
1. 为主应用(main-app)添加路由:
vue add router
2. 打开主应用(main-app)入口文件(main.js),修改部分代码:
直接上这部分代码:
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'react app', // app name registered
entry: '//localhost:3000',
container: '#home',
activeRule: '/',
},
{
name: 'vue app',
entry: { scripts: ['//localhost:8888/main.js'] },
container: '#about',
activeRule: '/vue',
},
]);
start();
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
由于原来添加路由在 src/views 目录下存在两个文件:
HomeView.vue AboutView.vue
改造这两个文件,和main.js中配置的对应:
四、创建子应用 react:
//全局安装 create-react-app 脚手架
npm install -g create-react-app
//创建项目
create-react-app child-react
改造 src 下的 index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
/**
* bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
export async function bootstrap() {
console.log('react app bootstraped');
}
/**
* 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
export async function mount(props) {
ReactDOM.render(<App />, props.container ? props.container.querySelector('#root') : document.getElementById('root'));
}
/**
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount(props) {
ReactDOM.unmountComponentAtNode(
props.container ? props.container.querySelector('#root') : document.getElementById('root'),
);
}
/**
* 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
*/
export async function update(props) {
console.log('update props', props);
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
reportWebVitals();
然后 npm start 把 react子应用跑起来,运行如下图:
五、创建 vue 子应用:
vue create child-vue
然后改造 vue 子应用的main.js
// src/main.js
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
// 定义一个Vue实例
let instance = null
// 渲染方法
function render(props = {}) {
const { container } = props
instance = new Vue({
render: (h) => h(App)
}).$mount(container ? container.querySelector('#app'): '#app')
}
// 独立运行时
if(!window.__POWERED_BY_QIANKUN__) {
render()
}
//暴露主应用生命周期钩子
/**
* bootstrap : 在微应用初始化的时候调用一次,之后的生命周期里不再调用
*/
export async function bootstrap() {
console.log('vue2-app bootstraped');
}
/**
* mount : 在应用每次进入时调用
*/
export async function mount(props) {
console.log('vue2-app mount', props);
render(props);
}
/**
* unmount :应用每次 切出/卸载 均会调用
*/
export async function unmount() {
console.log("vue2-app unmount")
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
}
修改 vue.config.js:
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
port: 8888
}
})
然后运行 vue 子应用即可
另外,有两个问题还没有解决:
1.子应用资源引入问题 ,默认使用的主应用的地址
2.主应用偶尔报错: