vue2使用qiankun框架笔记(更新中)
前言
本篇文章是针对vue项目巨石应用,对 qiankuan框架 的一份使用归纳,中间会记录一些遇到的问题和解决方案,如果喜欢自己探索的同学,也可以自行前往qiankun官网学习。同时也欢迎各位同学在评论区,说明自己遇到的问题,一同探讨。
1. 创建项目
1.1 创建项目和选择预置
vue create 项目名称
项目预置,选择手动选择功能
以下是项目预置选项参照,为了避免eslint配置的麻烦,就不使用了。着重说明qiankun框架的使用。
1.2 记录项目结构和依赖
项目结构如下
package.json
{
"name": "main-app",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"core-js": "^3.8.3",
"vue": "^2.6.14",
"vue-router": "^3.5.1",
"vuex": "^3.6.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"vue-template-compiler": "^2.6.14"
}
}
2. 使用qiankun框架(让微应用如iframe般嵌入到主应用中)
2.1 主应用下载乾坤,注册微应用
主应用下载qinakun:
npm i qiankun -S
主应用的main.js中注册微应用。
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
Vue.config.productionTip = false;
import { registerMicroApps, start } from "qiankun";
new Vue({
router,
store,
render: (h) => h(App),
}).$mount("#app");
// 根据路由配置
registerMicroApps([
{
name: "micro1", // 必须与微应用注册名字相同
entry: "http://localhost:8081", // 入口路径,开发时为微应用所启本地服务,上线时为微应用线上路径
container: "#micro-app", // 微应用挂载的节点
activeRule: "/micro1", // 当访问路由为 /micro-vue 时加载微应用
props: {
msg: "我是来自主应用的值-micro1", // 主应用向微应用传递参数
},
},
// {
// name: "micro2-app",
// entry: "http://localhost:8082",
// container: "#micro-app",
// activeRule: "/micro2",
// props: {
// msg: "我是来自主应用的值-micro2",
// },
// },
]);
start();
但是此时主应用还没有相关的container,让我们进行改造。
2.2 改造主应用,创建微应用DOM入口
(1)为了方便编写样式,下载sass和sass-loader,当然你也可以使用其他方案。
npm i sass
npm i sass-loader
(2)删除views文件夹中的原有文件,添加home.vue,修改路由文件和App.vue
router/index.js:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: () => import(/* webpackChunkName: "about" */ '../views/home.vue')
},
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
views/home.vue:
<template>
<div class="home-con">
<div class="nav-con">1</div>
<div class="bottom-con">
<div class="menu-con"></div>
<div class="main-con" id="micro-app"></div>
</div>
</div>
</template>
<script>
export default {
name: 'home'
}
</script>
<style lang="scss" scoped>
.home-con{
width: 100%;
height: 100%;
.nav-con{
width: 100%;
height: 50px;
background: #359e4a;
}
.bottom-con{
width: 100%;
height: calc(100% - 50px);
display: flex;
.menu-con{
flex: 2;
background: #2596d3;
}
.main-con{
flex: 8;
border: #2596d3 solid 1px;
}
}
}
</style>
App.vue:
<template>
<div id="app" class="main-app">
<router-view/>
</div>
</template>
<style>
html, body, #app{
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
</style>
此时重新运行项目,我们就有了一个很丑,但是结构清晰的主应用home页面。
2.3 改造微应用,创建主页
(1)下载sass和sass-loader
npm i sass
npm i sass-loader
(2)删除views文件夹中的原有文件,添加index.vue,修改路由文件和App.vue
views/index.vue:
<template>
<div class="micro-con">micro1-app</div>
</template>
<script>
export default {
}
</script>
<style lang="scss" scoped>
.micro-con {
width: 100%;
color: red;
}
</style>
router/index.js:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'index',
component: () => import(/* webpackChunkName: "about" */ '../views/index.vue')
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
App.vue:
<template>
<div id="microApp" class="micro1-app">
<router-view/>
</div>
</template>
<style>
html, body, #microApp{
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
</style>
此时你就拥有了一个简单的应用主页。
2.4 将主应用和微应用建立通信(主要修改微应用)
此模块内容可参照 qiankun-项目实践
(1)主应用尝试直接调用微应用
可以看到,主应用无法直接和微应用建立联系,有跨域问题。所以需要对微应用进行修改
(2)在 src 目录新增 public-path.js:
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
(3)入口文件 main.js 修改,为了避免根 id #app 与其他的 DOM 冲突,需要限制查找范围。
import './public-path';
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './App.vue';
import routes from './router';
import store from './store';
Vue.config.productionTip = false;
let router = null;
let instance = null;
function render(props = {}) {
const { container } = props;
router = new VueRouter({
// micro1和主应用的registerMicroApps配置对应
base: window.__POWERED_BY_QIANKUN__ ? '/micro1/' : '/',
mode: 'history',
routes,
});
instance = new Vue({
router,
store,
render: (h) => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时
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;
router = null;
}
(3)打包配置修改(vue.config.js):
const { name } = require('./package');
module.exports = {
devServer: {
headers: {
'Access-Control-Allow-Origin': '*', // 允许跨域
},
port: 8081 // 端口号自定义,和主应用中main.js的registerMicroApps的配置一致即可。
},
configureWebpack: {
output: {
library: `${name}-[name]`,
libraryTarget: 'umd', // 把微应用打包成 umd 库格式
chunkLoadingGlobal: `webpackJsonp_${name}`, // webpack 5 需要把 jsonpFunction 替换成 chunkLoadingGlobal
},
},
};
(4)修改微应用router/index.js:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/index',
name: 'index',
component: () => import(/* webpackChunkName: "about" */ '../views/index.vue')
}
]
export default routes
这一步完成后,访问 http://localhost:8080/micro1/index,会有错误提示:
application 'micro1' died in status LOADING_SOURCE_CODE: [qiankun]: Target container with #micro-app not existed while micro1 loading!
看到这里,恭喜你,快成功了,看下一步 2.6 解决。
2.6 在主应用注册微应用路由,即可访问微应用页面
在主应用注册微应用路由,完成这步后,主应用就可以使用对应路由规则,访问微应用micro1-app上的路由页面了。
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: () => import(/* webpackChunkName: "about" */ '../views/home.vue'),
children: [
{ path: "/micro1/*", name: "micro1" },
]
},
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
此时打开http://localhost:8080/micro1/index,发现微应用的页面出现在了主应用中。
3. 微应用之间的路由切换
3.1 同个微应用之间的路由切换
直接使用 this.$router.push 即可。
3.2 不同微应用之间的路由切换
参照官网 https://qiankun.umijs.org/zh/faq#微应用之间如何跳转,有3种方式,最简单的方式就是通过 window.location.href
进行跳转,比如:
<template>
<div class="micro-con">
<div>micro1-app</div>
<div @click="goMicro2()">点击,切换到micro2-app</div>
</div>
</template>
<script>
export default {
methods: {
goMicro2() {
// this.$router.push 方法只能在同个微应用中使用,微应用之间可以参照 https://qiankun.umijs.org/zh/faq#%E5%BE%AE%E5%BA%94%E7%94%A8%E4%B9%8B%E9%97%B4%E5%A6%82%E4%BD%95%E8%B7%B3%E8%BD%AC
window.location.href = 'http://localhost:8080/micro2/index'
}
}
}
</script>
<style lang="scss" scoped>
.micro-con {
width: 100%;
color: red;
}
</style>