乾坤(qiankun)结合vue入门
前言
- 官方入门教程 :https://qiankun.umijs.org/zh/cookbook
- 微应用路由模式选择:location.pathname--hash
- demo参考
- 常见问题
- 在主应用的某个路由页面加载微应用
注意事项
- 主应用和各个微应用之间挂载id(app)命名尽量保持不同,避免挂载被覆盖,同时也方便调试
- 微应用路由应该和主应用注册微应用的路由相同
主应用
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
//主应用 配置
import "./qiankunconfig"
Vue.config.productionTip = false
Vue.use(ElementUI);
new Vue({
router,
store,
render: function (h) {
return h(App)
}
}).$mount('#app')
qiankunconfig
import { registerMicroApps } from 'qiankun';
//微应用配置
registerMicroApps([
{
//名称不能重复
name: 'embedChild',
entry: '//localhost:8080',
//挂载在主应用的dom id
container: '#father-child',
//与微应用匹配的路由
activeRule: '/home/child1',
},
{
name: 'embedChild2',
entry: '//localhost:8080',
container: '#father-child',
activeRule: '/home/child2',
},
]);
//在主应用路由页mounted start
// start();
vue-router路由配
import Vue from 'vue'
import VueRouter from 'vue-router'
import home from '@/views/Index/home'
Vue.use(VueRouter)
const routes = [
{path: '/', redirect: '/home'},
{
path: '/home/*',
name: 'home',
component: home,
children:[
{path: '/child2', name: 'child2'},
{path: '/child1', name: 'child1'},
]
},
{
path: '/home',
name: 'home',
component: home,
},
// {path: '/father', name: 'father', component: father},
]
const router = new VueRouter({
mode:'history',
routes
})
export default router
app.vue
直接挂router-view
<template>
<div>
<router-view/>
</div>
</template>
home.vue
主应用聚合页面
<template>
<el-container>
<el-header>Header</el-header>
<el-container>
<el-aside width="200px">
<el-menu
default-active="2"
class="el-menu-vertical-demo">
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title"><router-link to="/home/child1">子模块1</router-link></span>
</el-menu-item>
<el-menu-item index="3">
<i class="el-icon-document"></i>
<span slot="title"><router-link to="/home/child2">子模块2</router-link></span>
</el-menu-item>
</el-menu>
</el-aside>
<el-main>
<div id="father-child">
</div>
</el-main>
</el-container>
</el-container>
</template>
<script>
import {start} from 'qiankun';
export default {
mounted() {
//避免重复加载
if (!window.qiankunStarted) {
window.qiankunStarted = true;
start();
}
},
data() {
return {}
},
created() {
},
methods: {},
}
</script>
<style lang='less' scoped>
.el-header, .el-footer {
background-color: #B3C0D1;
color: #333;
text-align: center;
line-height: 60px;
}
.el-aside {
background-color: #D3DCE6;
color: #333;
text-align: center;
line-height: 700px;
}
.el-main {
background-color: #E9EEF3;
color: #333;
text-align: center;
line-height: 160px;
}
body > .el-container {
margin-bottom: 40px;
}
.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
line-height: 260px;
}
.el-container:nth-child(7) .el-aside {
line-height: 320px;
}
</style>
微应用
main.js
import Vue from 'vue'
import './public-path';
export {bootstrap, mount, unmount, update} from './qiankunconfig'
import {render} from './qiankunconfig'
Vue.config.productionTip = false
// 独立运行时挂载dom
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
qiankunconfig
注意:微应用需要在自己的入口 js (通常就是你配置的 webpack 的 entry js) 导出 bootstrap、mount、unmount 三个生命周期钩子,以供主应用在适当的时机调用。
import Vue from 'vue';
import router from "@/router";
import App from "@/App";
let instance = null
export const render = () => {
instance = new Vue({
router,
render: h => h(App)
}).$mount('#child1Root');
}
/**
* bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
export async function bootstrap() {
console.log('child1-bootstrap');
}
/**
* 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
export async function mount(props) {
console.log(`child1-mount-props:${JSON.stringify(props)}`);
render(props)
}
/**
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount(props) {
console.log(`child1-unmount-props:${JSON.stringify(props)}`);
instance.$destroy();
}
/**
* 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效
*/
export async function update(props) {
console.log(`child1-update-props:${JSON.stringify(props)}`);
}
router配置
import Vue from 'vue'
import VueRouter from 'vue-router'
import child1 from "@/components/childFirst";
import child2 from "@/components/childSeconde";
Vue.use(VueRouter)
const routes = [
{path: '/', redirect: '/child1'},
{
path: '/child1',
name: 'child1',
component: child1
},
{
path: '/child2',
name: 'child2',
component: child2
},
]
const router = new VueRouter({
mode: 'history',
base: window.__POWERED_BY_QIANKUN__ ? '/home' : '/',
routes
})
export default router