qiankun+vue构建主应用
# 引言
本教程将引导大家将普通的vue项目改造成qiankun
微前端基座。
# 构建主应用基座
我们先使用vue-cli
生成一个Vue
的项目,初始化主应用。本教程使用的是vue-cli4
版本,如果版本低的可以先升级。
将普通的项目改造成qiankun
主应用基座,需要进行三步操作:
- 创建微应用容器 - 用于承载微应用,渲染显示微应用;
- 注册微应用 - 设置微应用激活条件,微应用地址等等;
- 启动
qiankun
;
# 创建微应用容器
- 在主应用中创建微应用的承载容器,这个容器规定了微应用的显示区域,微应用将在该容器内渲染并显示。我们先设置主应用自身的路由。代码如下:
// src/router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path:"/",
name:"Home",
component:() => import("../pages/start.vue") //开始界面
},
{
path:"/login",
name:"Login",
component:() => import("../pages/login.vue"), //登录界面
meta:{
fullscreen:true //是否全屏
}
}
]
export default new VueRouter({ //网上大多数都是使用history模式,但是我使用的是hash模式
routes
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from "./router"
import store from './store'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app')
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
- 设置主应用的布局,我们会有一个菜单和显示区域,代码实现如下: 首先是菜单配置:(目前只有主应用的一个页面要显示在菜单上)
// src/data/nav.js
export default [
{
title: "开始",
path: "/",
}
]
1
2
3
4
5
6
7
2
3
4
5
6
7
这是App.vue
。我将布局写在了layout
中。
// src/App.vue
<template>
<div class="main-contenter">
<layout></layout>
</div>
</template>
<script>
export default {
name: 'App',
components:{
layout: () => import("@/layout/index.vue")
},
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
接下来查看layout
// src/layout/index.vue
<template>
<div class="layout-content">
<div class="header" v-if="!$route.meta.fullscreen">
<!--头部组件-->
<header-component></header-component>
</div>
<div class="content">
<div class="nav" v-if="!$route.meta.fullscreen">
<!--导航组件-->
<nav-component></nav-component>
</div>
<div class="frame-wrapper" :style="$route.name&&!$route.meta.fullscreen?'padding:10px;':'padding:0px;'">
<!-- 主应用渲染区,用于挂载主应用路由触发的组件,使用$route.name来判断是不是主应用组件 -->
<router-view v-show="$route.name"></router-view>
<!--子应用渲染区,用户挂载子应用节点-->
<div v-show="!$route.name" id="frame" :style="!$route.name&&!$route.meta.fullscreen?'padding:10px;':'padding:0px;'"></div>
</div>
</div>
</div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
nav.vue
是用来渲染左侧导航栏的组件
// src/layout/nav.vue
<template>
<div class="nav-content">
<el-menu>
<template v-for="(item,index) in navData">
<el-menu-item @click="goto(item.path)" :index="'nav'+index" :key="'nav'+index" v-if="!item.children || item.children.length == 0">
<span slot="title"><span v-pre>{{item.title}}</span></span>
</el-menu-item>
<el-submenu v-if="item.children && item.children.length > 0" :index="'nav'+index" :key="'nav'+index">
<span slot="title"><span v-pre>{{item.title}}</span></span>
<el-menu-item @click="goto(child.path)" v-for="(child,idx) in item.children" :key="'nav'+index+'-'+idx" :index="'nav'+index+'-'+idx"><span v-pre>{{child.title}}</span></el-menu-item>
</el-submenu>
</template>
</el-menu>
</div>
</template>
<script>
import navData from "@/data/nav.js"
export default {
data(){
return {
navData:navData
}
},
methods:{
goto(path){
this.$router.push(path)
}
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 注册微应用
构建好主框架后,我们需要使用qiankun
的registerMicroApps
方法注册微应用,代码实现如下:
首先主应用安装qiankun
npm install qiankun -S
1
// src/micro/app.js
//此时我们还没有微应用,所以app为空
const apps = [
/**
* name: 微应用名称 - 具有唯一性
* entry: 微应用入口 - 通过该地址加载微应用
* container: 微应用挂载节点 - 微应用加载完成后将挂载在该节点上
* activeRule: 微应用触发的路由规则 - 触发路由规则后将加载该微应用
*/
]
export default apps
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
// src/micro/index.js
import {
registerMicroApps,
addGlobalUncaughtErrorHandler,
start,
} from "qiankun";
// 微应用注册信息
import apps from "./apps";
/**
* 注册微应用
* 第一个参数 - 微应用的注册信息
* 第二个参数 - 全局生命周期钩子
*/
registerMicroApps(apps, {
// qiankun 生命周期钩子 - 微应用加载前
beforeLoad: (app) => {
console.log("before load", app.name);
return Promise.resolve();
},
// qiankun 生命周期钩子 - 微应用挂载后
afterMount: (app) => {
console.log("after mount", app.name);
return Promise.resolve();
},
});
/**
* 添加全局的未捕获异常处理器
*/
addGlobalUncaughtErrorHandler((event) => {
console.error(event);
const { msg } = event;
// 加载失败时提示
if (msg && msg.includes("died in status LOADING_SOURCE_CODE")) {
console.error("微应用加载失败,请检查应用是否可运行");
}
});
// 导出 qiankun 的启动函数
export default start;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
从上面可以看出,我们的微应用注册信息在apps
数组中(此时为空,我们在后面接入微应用时会添加微应用注册信息),然后使用 qiankun
的 registerMicroApps
方法注册微应用,最后导出了start
函数,注册微应用的工作就完成啦!
# 启动主应用
我们在注册好了微应用,导出start
函数后,我们需要在合适的地方调用start
启动主应用。
本例中我们在layout的mounted钩子中启动qiankun
主应用,以保证主应用加载时容器已经加载完毕,代码如下:
// src/layout/index.vue
//导入start函数
import startQiankun from "@/micro"
export default {
data(){
return{
}
},
components:{
headerComponent:() => import("@/layout/header.vue"),
navComponent:() => import("@/layout/nav.vue")
},
mounted(){
//启动主应用
startQiankun()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
至此,主应用改造完毕!
上次更新: 2021/07/22, 09:07:42