微服务一般分为主应用和子应用,首先创建一个主应用项目和一个子应用项目
一、主应用、子应用安装qiankun、vite-plugin-qiankun这两个依赖
二、主应用、子应用使用vite-plugin-qiankun插件
import qiankun from "vite-plugin-qiankun";
import { defineConfig, loadEnv } from 'vite'
import path from 'path';
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx';
import qiankun from "vite-plugin-qiankun";
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
export default defineConfig((config) => {
const { VITE_APP_OUTPUT_DIR } = loadEnv(config.mode, process.cwd());
console.log(VITE_APP_OUTPUT_DIR,"---VITE_APP_OUTPUT_DIR");
return {
base: `/main_demo`,
server: {
host: true,
port: 1028,
headers: {
'Access-Control-Allow-Origin': '*'
},
open: true,
proxy: {},
},
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
},
plugins: [
vue(),
vueJsx(),
qiankun('ms-envpro', { // 微应用名字,与主应用注册的微应用名字保持一致
useDevMode: true,
}),
AutoImport({
imports: ["vue", "vue-router"],
vueTemplate: true,
eslintrc: {
// true--每次都会生成eslintrc-auto-import
enabled: true,
filepath: './.eslintrc-auto-import.json',
globalsPropValue: true
},
dts: true // 路径下自动生成文件夹存放全局指令
}),
// @components目录下的.vue,.js文件会被自动导入
Components({
dirs: ['src/components/'],
extensions: ['vue'],
deep: true,
// 不需要生成.d.ts文件
dts: true,
// 注册组件的相对目录
// 组件的扩展名
// 允许后面导入的同名组件覆盖前面的
allowOverrides: true
}),
]
}
})
三、创建子应用入口
1.新建qiankun文件夹
demo1、demo2分别代表两个子应用入口
2.入口文件配置
<script setup>
import { registerMicroApps, runAfterFirstMounted, start } from "qiankun/es"
import { router } from "../../router/index";
onMounted(() => {
initQiankun()
})
const yxhj = 'DEV'
const entrys = {
'LOCAL': 'http://localhost:1029/demo1',
'DEV': 'http://192.168.0.125:1029/demo1',
'TEST': 'http://192.168.0.206:9092/examcs',
}
const oneApps = [
{
name: 'demo1',
entry: `${entrys[yxhj]}`,
container: '#demo1',
activeRule: `/main_demo/demo1`,
props: { data: 'demo1', mainAppRouter: history, router }
}
]
const initQiankun = () => {
registerMicroApps(oneApps, {})
runAfterFirstMounted(() => { })
start({ prefetch: true })
}
</script>
<template>
<div id="demo1">
</div>
</template>
<style scoped lang="scss">
#demo1 {
height: 100%;
}
</style>
四、主应用配置子应用路由匹配
import { createRouter, RouteRecordRaw, RouterHistory } from 'vue-router';
import Index from '../views/index/index.vue';
import { App } from 'vue';
export let router: any
const routes: RouteRecordRaw[] = [
{
path: '/',
component: () => import("@/views/layout/index.vue"),
redirect: '/index',
children: [
{
path: '/index',
name: 'index',
component: Index
},
{
path: `/demo1/:path`,
name: "demo1",
component: () => import("@/views/qiankun/demo1.vue")
},
{
path: `/demo2/:path`,
name: "demo2",
component: () => import("@/views/qiankun/demo2.vue")
},
]
}
];
export async function setupRouter(app: App<Element>, history: RouterHistory) {
router = createRouter({
history,
routes,
});
app.use(router)
await router.isReady();
}
export function initRouter() {
router = null
}
五、子应用乾坤配置
1.路由提取成方法暴露出去
import { createRouter, RouteRecordRaw, RouterHistory } from 'vue-router';
import Index from '../views/index/index.vue';
import { App } from 'vue';
export let router: any
const routes: RouteRecordRaw[] = [
{
path:'/',
redirect:'/index',
},
{
path: '/index',
name: 'index',
component: Index
},
{
path: `/home`,
name: "home",
component: () => import("../views/home.vue")
},
];
export async function setupRouter(app: App<Element>, history: RouterHistory, isPoweredByQiankun: boolean | undefined) {
router = createRouter({
history,
routes,
});
console.log(isPoweredByQiankun,"----isPoweredByQiankun???");
app.use(router)
await router.isReady();
}
export function initRouter() {
router = null
}
main.ts配置如下
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { setupRouter,initRouter } from './router'
import { createWebHistory } from 'vue-router';
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper';
let app: any
let history: any
async function setupApp(props: any) {
const isPoweredByQiankun = qiankunWindow.__POWERED_BY_QIANKUN__;
console.log(isPoweredByQiankun,"---子应用 isPoweredByQiankun");
const container = props ? props.container : undefined;
const base = `/demo1`;
const mainbase = 'main_demo';
history = createWebHistory(isPoweredByQiankun ? `/${mainbase}${base}` : base);
app = createApp(App);
// 注册路由
await setupRouter(app, history, isPoweredByQiankun);
app.mount(container ? container.querySelector('#app') : '#app')
}
renderWithQiankun({
mount(props) {
props.onGlobalStateChange((state: any) => {
console.log('子应用接收的参数', state);
});
setupApp(props);
console.log(props,"---props");
app.config.globalProperties.$parentRouter = props.router;
app.config.globalProperties.$onGlobalStateChange = props.onGlobalStateChange;
app.config.globalProperties.$setGlobalState = props.setGlobalState;
},
bootstrap() {
console.log('%c%s', 'color: green;', 'vue3.0 app bootstraped');
},
unmount() {
app.unmount();
app._container.innerHTML = '';
app = null;
initRouter();
history.destroy();
},
update() {
console.log('update');
}
});
if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
setupApp(undefined);
}
六、主应用、子应用一定要配置跨域问题!
server: {
host: true,
port: 1029,
headers: {
'Access-Control-Allow-Origin': '*'
},
open: true,
proxy: {},
}
以上就是在vue3中配置乾坤微服务全部流程