前言
这边主要是以vue3为主应用,引入vue2作为子应用,先进行初次尝试。
搭建
初始化主项目
这边主要以 vue3 为 主项目 进行构建
- 初始化
#这边选择vue3进行初始化
vue create main
cd main
yarn add vue-loader-v16 vue-router@4 --save
当前 目录 结构
- 在src下面新建 router/index.js文件
import {
createRouter,
createWebHashHistory
} from 'vue-router';
const routes = [
{
path: '/index',
name: 'Index',
component: () => import('../views/index/index')
}
]
export default createRouter({
history: createWebHashHistory('/vue3'),
routes,
});
- 新建 /src/views/index/index.vue 文件
<template>
<div id="main" @click="handleClick">This is Main{{count}}</div>
<div id="child1">This is child1</div>
<div id="child2">This is child2</div>
</template>
<script setup>
import {
ref
} from 'vue'
const count = ref(0);
function handleClick() {
count.value++;
}
</script>
<style>
#main,
#child1,
#child2 {
width: 300px;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
}
#main {
height: 60px;
background: #000066;
}
#child1 {
height: 100px;
background: #FF4400;
}
#child2 {
height: 100px;
background: #31A354;
}
</style>
- 修改App.vue
<template>
<router-view></router-view>
</template>
<script>
export default {
name: 'App',
components: {}
}
</script>
- 修改 main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router';
createApp(App).use(router).mount('#app')
- 启动主应用服务 yarn serve
- 访问: http://localhost:8080/#/index 或者 http://localhost:8080/vue3#/index
初始化子项目
- 初始化
vue create vue2
cd vue2
- 修改 App.vue
<template>
<div>hello,我是vue2</div>
</template>
<script>
export default {
name: 'App',
components: {}
}
</script>
- 配置 vue.config.js,设置端口为8081
const path = require('path');
module.exports = {
devServer: {
contentBase: path.join(__dirname, 'dist'),
hot: true,
port: 8081,
},
};
- 启动项目 yarn serve
- 访问:
配置主项目
- 下载qiankun
cd main
yarn add qiankun --save
- 修改main.js
//...
import { registerMicroApps } from 'qiankun';
registerMicroApps([
{
name: 'vue2 app', // app name registered
entry: '//localhost:8081',
container: '#child1',
activeRule: '/vue3',
},
]);
createApp(App).use(router).mount('#app')
- 配置views/index/index.vue
import {
ref,
onMounted
} from 'vue'
import { start } from 'qiankun';
onMounted(function() {
setTimeout(()=>{
//这边主要是确保start只执行一次,执行的时候,且确保挂载的dom已经存在。
if (!window.qiankunStarted) {
window.qiankunStarted = true;
start();
}
}, 2000)
})
配置子项目
- 修改 public/index.vue,主要是修改app挂载的domId,需要与main.js一一对应
<div id="app-vue2"></div>
- 配置 main.js
const app = new Vue({
render: h => h(App),
})
/**
* bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
export async function bootstrap() {
console.log('vue2 app bootstraped');
}
/**
* 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
export async function mount(props) {
console.log('vue2 app mount', props);
app.$mount('#app-vue2')
}
/**
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount(props) {
console.log('unmount props', props);
}
/**
* 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
*/
export async function update(props) {
console.log('update props', props);
}
- 修改 vue.config.js
const path = require('path');
function resolve(dir) {
return path.join(__dirname, dir);
}
const packageName = require('./package.json').name;
module.exports = {
publicPath: 'http://localhost:8081',
filenameHashing: true,
devServer: {
contentBase: path.join(__dirname, 'dist'),
hot: true,
disableHostCheck: true,
port: 8081,
headers: {
'Access-Control-Allow-Origin': '*',
},
},
configureWebpack: {
output: {
library: `${packageName}-[name]`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${packageName}`,
},
}
};
结果
在main和vue2下面分别启动服务
访问 http://localhost:8080/vue3#/index
如图可见,可以看到vue2 的 我是vue2 已经挂载到了vue3的下面了。
扩展
这次我们只是简单的做一个单页面引用,其实内部的实现原理还是比较模糊不清的,例如:复杂用法、实现原理、qiankun的生命周期、registerMicroApps和start方法做了什么?需要我们接下来再继续探索。
注意事项
- 子应用挂载的位置,在start之前必须已经挂载好了
- 子应用需要允许跨域访问