微前端vue实例-乾坤【qiankun】
- 一、前言
- 二、乾坤实例应用
- STEP1:前期准备工作【需关注代码注释重点部分】
- 1. 创建主应用【qiankun-main】
- 2. 创建子应用【qiankun-vue-child】
- STEP2:乾坤简单配置步骤【主要内容】
- 1. 主应用配置【qiankun-main】
- 2. 子应用配置【qiankun-vue-child】
- 附加
一、前言
功能说明:
- 此实例包含有一个
qiankun-main
主应用和qiankun-vue-child
子应用。【可以包含若干个子应用,这里只建立一个vue子应用进行演示】- 主应用跨域访问子应用系统。
qiankun-main
主应用运行端口8085
,qiankun-vue-child
子应用运行端口8083
。【由于使用了vue create
创建vue项目,故需在项目文件夹下手动创建vue.config.js
进行配置,下面会讲到】- 参考文档:qiankun 官方文档
二、乾坤实例应用
STEP1:前期准备工作【需关注代码注释重点部分】
1. 创建主应用【qiankun-main】
- 新建主应用。
vue create qiankun-main
- 创建
src/components/father.vue
,内容如下:
<template>
<div>我是father</div>
</template>
<script>
export default {
name: "father"
}
</script>
-
src/router/index.js
中添加路由信息,内容如下:
import Router from 'vue-router'
export default new Router({
mode:'history',
base:'',
routes: [
{ path: '/', redirect: '/father'},
{ path:'/father', component: ()=> import('@/components/father')}
]
})
- 在
main.js
中引入路由,内容如下:
import Vue from 'vue';
import App from './App.vue'
import Router from 'vue-router'
import router from "./router"
Vue.use(Router)
new Vue({
router,
render: h => h(App),
}).$mount('#app')
- 在项目根目录下新建
vue.config.js
,添加内容如下:
module.exports ={
devServer: {
port: 8085,
headers: { // 重点1: 允许跨域访问子应用页面
'Access-Control-Allow-Origin': '*',
}
}
}
- 修改app.vue中的内容,如下:
<template>
<div class="app">
<span><router-link to="/">点击跳转到父页面</router-link></span>
<span><router-link to="/vue">点击跳转到子页面</router-link></span>
<router-view />
<div id="vue"></div> <!-- 重点2:子应用容器 id -->
</div>
</template>
- 测试:运行程序后,浏览器打开本地
http://localhost:8085/father
,能成功显示father.vue页面的内容。结果如下:
2. 创建子应用【qiankun-vue-child】
- 新建子应用。
vue create qiankun-vue-child
- 创建
src/components/child.vue
,内容如下:
<template>
<div>我是child</div>
</template>
<script>
export default {
name: "child"
}
</script>
-
src/router/index.js
中添加路由信息,内容如下:
import Router from 'vue-router'
import '../public-path' // 重点3: 引入public-path文件
export default new Router({
base: window.__POWERED_BY_QIANKUN__ ? '/vue' : '/', // 重点4
mode: 'history', // 重点5
routes: [
{ path:'/', redirect: '/child'},
{ path: '/child', component: ()=>import('../components/child')}]
})
- 在
main.js
中引入路由,内容如下:
import Vue from 'vue';
import App from './App.vue'
import Router from 'vue-router'
import router from "./router"
Vue.use(Router)
new Vue({
router,
render: h => h(App),
}).$mount('#app')
- 在项目根目录下新建
vue.config.js
,添加内容如下:
const { name } = require('./package');
module.exports = {
devServer: {
port: 8083, // 重点6
headers: { // 重点7:同重点1,允许子应用跨域
'Access-Control-Allow-Origin': '*',
},
},
// 自定义webpack配置
configureWebpack: {
output: {
library: `${name}-[name]`,
libraryTarget: 'umd', // 把子应用打包成 umd 库格式
jsonpFunction: `webpackJsonp_${name}`,
},
},
};
- 修改app.vue中的内容,如下:
<template>
<div class="app">
我是子应用的内容
<router-view />
</div>
</template>
- 测试:运行程序后,浏览器打开本地
http://localhost:8083/child
,能成功显示father.vue页面的内容。结果如下:
STEP2:乾坤简单配置步骤【主要内容】
1. 主应用配置【qiankun-main】
- 安装乾坤。【说明:主应用需要安装乾坤依赖,子应用均不需要,但子应用需要暴露生命周期方法给主应用】
$ yarn add qiankun # 或者 npm i qiankun -S
- 在主应用入口文件
src/main.js
中注册子应用。
import Vue from "vue"
import App from "./App.vue"
import Router from 'vue-router'
import router from "./router"
import { registerMicroApps, start } from "qiankun"
Vue.use(Router);
Vue.config.productionTip = false;
new Vue({
router,
render: h => h(App),
}).$mount('#app');
// 在主应用中注册子应用
registerMicroApps([
{
name: "vue app",
entry: "//localhost:8083", // 重点8:对应重点6
container: '#vue', // 重点9:对应重点2
activeRule: '/vue' // 重点10:对应重点4
}]
);
// 启动
start();
2. 子应用配置【qiankun-vue-child】
- 在src目录新增
public-path.js
,内容如下:
if (window.__POWERED_BY_QIANKUN__) {
// eslint-disable-next-line no-undef
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}
- 在
main.js
中配置如下:
import Vue from 'vue';
import App from './App.vue'
import Router from 'vue-router'
import router from "./router/index"
// new Vue({
// router,
// render: h => h(App),
// }).$mount('#app')
Vue.use(Router);
Vue.config.productionTip = false;
let instance = null;
function render( props = {}) {
const { container } = props;
instance = new Vue({
router,
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] vue app bootstraped');
}
export async function mount(props) {
console.log('[vue] props from main framework', props);
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
}
说明:子应用的四个周期函数:
bootstrap
:bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。mount
:应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法。unmount
:应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例。update
:可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效。
在本地启动qiankun-main
和qiankun-vue-child
之后,浏览器打开本地http://localhost:8085/vue/child
,结果如下:
附加
- 设置默认启动子应用,与子应用
activeRule
设置的值一样。
结果:当打开qiankun-main
主页面,默认为/vue
系统的主页面。
- import { registerMicroApps, start } from "qiankun"
+ import { registerMicroApps, start, setDefaultMountApp } from "qiankun"
...
+ setDefaultMountApp("/vue");
// 启动
start();
- 主应用给子应用传值。
修改1:主应用【qiankun-main】-main.js
// 在注册子应用的时候添加props属性
registerMicroApps([
{
name: "vue App",
entry: "//localhost:8083",
container: '#vue',
activeRule: '/vue',
+ props: {
+ appContent: '我是子应用传给主应用的值'
+ }
}]
);
修改2:子应用【qiankun-vue-child】-main.js
function render(props = {}) {
- const { container } = props;
+ const {container, appContent} = props;
instance = new Vue({
router,
+ data() {
+ return {
+ content: appContent
+ }
+ },
- render: h => h(App)
+ render(h) {
+ return h(App, {
+ props: {
+ content: this.content
+ }
+ })
+ }
}).$mount(container ? container.querySelector('#app') : '#app'); // 为了避免根id#app与其他DOM冲突,需要限制查找范围
}
修改3:子应用【qiankun-vue-child】-App.vue
<template>
<div class="app">
{{ content }}
<router-view />
</div>
</template>
<script>
export default {
name: 'App',
props:{
content: {
type: String,
default: 'child没有接收到main的数据'
}
}
}
</script>
结果: