Vue3+vite与Qiankun实现的微前端Demo
关于Qiankun
qiankun 是一个基于 single-spa 的微前端实现库,旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。
官方文档: https://qiankun.umijs.org/zh/guide
操作步骤
创建主应用
1pnpm create vue
2Project name: main
3cd main
4pnpm add qiankun -S
5pnpm install
6pnpm dev
main.ts
1import { createApp } from 'vue'
2import App from './App.vue'
3import router from './router'
4
5
6import { registerMicroApps, start } from "qiankun";
7
8const app = createApp(App)
9
10const apps: any[] = [
11 {
12 name: "app1", // 应用的名字
13 entry: "http://localhost:9001/", // 默认加载这个html,解析里面的js动态的执行(子应用必须支持跨域,内部使用的是 fetch)
14 container: "#app1", // 要渲染到的节点id,对应上一步中src/App.vue中的渲染节点
15 activeRule: "/apps/app1"
16 },
17 {
18 name: "app2",
19 entry: "http://localhost:9002/",
20 container: "#app2",
21 activeRule: "/apps/app2"
22 },
23];
24registerMicroApps(apps); // 注册应用
25start({
26 prefetch:'all', // 预加载
27 sandbox: {
28 //experimentalStyleIsolation: true, // 开启沙箱模式,实验性方案
29 },
30}); // 开启应用
31
32app.use(router)
33app.mount('#app')
App.vue
1 <nav>
2 <RouterLink to="/">Home</RouterLink>
3 <RouterLink to="/about">About</RouterLink>
4 <!-- 新增app1路由 -->
5 <router-link to="/apps/app1">app1</router-link>
6 <!-- 新增app1路由 -->
7 <router-link to="/apps/app1/about">app1/about</router-link>
8 <!-- 新增app2路由 -->
9 <router-link to="/apps/app2">app2</router-link>
10 </nav>
11 <RouterView />
12 <!-- 新增site1渲染节点 -->
13 <div id="app1" />
14 <!-- 新增app2渲染节点 -->
15 <div id="app2" />
创建app1
1pnpm create vue
2Project name: app1
3cd app1
4pnpm add vite-plugin-qiankun -S
5pnpm install
6pnpm dev
vite.config.ts
1import { fileURLToPath, URL } from 'node:url'
2
3import { defineConfig } from 'vite'
4import vue from '@vitejs/plugin-vue'
5import qiankun from 'vite-plugin-qiankun'
6
7// https://vitejs.dev/config/
8export default defineConfig({
9 server: {
10 watch: { usePolling: true },
11 hmr: true,
12 port: 9001,
13 headers: {
14 'Access-Control-Allow-Origin': '*', // 主应用获取子应用时跨域响应头
15 },
16 },
17 plugins: [
18 vue(),
19 qiankun('vue3', {
20 useDevMode: true
21 })
22 ],
23 resolve: {
24 alias: {
25 '@': fileURLToPath(new URL('./src', import.meta.url))
26 }
27 }
28})
main.ts
1import { createApp } from "vue";
2import router from "./router";
3import App from "./App.vue";
4import {
5 renderWithQiankun,
6 qiankunWindow,
7 QiankunProps,
8} from "vite-plugin-qiankun/dist/helper";
9const initQianKun = () => {
10 renderWithQiankun({
11 // bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap
12 // 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等
13 bootstrap() {
14 console.log("bootstrap app1");
15 },
16 // 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法,也可以接受主应用传来的参数
17 mount(_props: any) {
18 console.log("mount", _props);
19 render(_props.container);
20 },
21 // 应用每次 切出/卸载 会调用的unmount方法,通常在这里我们会卸载微应用的应用实例
22 unmount(_props: any) {
23 console.log("unmount", _props);
24 },
25 update: function (props: QiankunProps): void | Promise<void> {
26 console.log("update");
27 },
28 });
29};
30
31const render = (container) => {
32 // 如果是在主应用的环境下就挂载主应用的节点,否则挂载到本地
33 const appDom = container ? container : "#app";
34 const app = createApp(App);
35 app.use(router);
36 app.mount(appDom);
37};
38// 判断是否为乾坤环境,否则会报错iqiankun]: Target container with #subAppContainerVue3 not existed while subAppVue3 mounting!
39qiankunWindow.__POWERED_BY_QIANKUN__ ? initQianKun() : render(null);
router/index.ts
1
2import { createRouter, createWebHistory } from 'vue-router'
3import { qiankunWindow } from "vite-plugin-qiankun/dist/helper";
4const router = createRouter({
5 history: createWebHistory(qiankunWindow.__POWERED_BY_QIANKUN__ ? "/apps/app1" : "/"),
6 routes: [
7 {
8 path: '/',
9 name: 'home',
10 component: () => import('../views/Home.vue')
11 },
12 {
13 path: '/about',
14 name: 'about',
15 component: () => import('../views/About.vue')
16 },
17 {
18 path: '/:catchAll(.*)',
19 name: "404",
20 component: () => import('../App.vue')//这个是我自己的路径
21 },
22 ]
23})
24
25export default router
创建app2
与app1创建方式相同,只是名称不同
启动
分别在main/app1/app2目录下执行pnpm dev
,浏览器访问 http://localhost:5173/ 即可
踩坑点
- 由于应用的路由不在
router/index.ts
里,请求应用路由时会出现[Vue Router warn]: No match found for location with path
的提示,在路由表中加/:catchAll(.*)
可解决该类问题 - initQianKun.mount 调用render时,要有完整的createApp().mount(),当你切换应用时,这个逻辑会重新调用。
- 子应用的全局样式,会影响主应用,所以设计的时候要做到样式隔离
项目地址
https://github.com/vue-qiankun/vue3-vite-qiankun-demo
发布日期:2023-08-02 20:14 字数:528 用时
相关文章
标签云
alpine(1) api网关(1) async(1) await(1) centos(4) cli(1) client-go(1) debug(1) docker(10) docker-compose(1) dockerfile(1) embed(1) es6(1) etcd(1) etcdctl(1) freemesh(2) git(6) go(5) go-zeus(5) goland(2) golang(7) grafana(2) grpc(5) grpcurl(1) homebrew(1) homedir(1) http(2) hugo(1) java(2) javascript(3) job(1) js(1) json(1) k8s(16) k8s部署指南(1) kubebuilder(1) kubectl(4) kubernetes(1) linux(2) localecompare(1) lombok(1) metrics(2) mock(1) mysql(1) npm(1) nsenter(1) nvm(1) pnpm(2) pprof(1) prettier(1) prometheus(2) protobuf3(1) protoc(1) qiankun(1) request(1) scss(1) servicemesh(1) spring(1) springcloud->freemesh(1) ssh(2) systemctl(1) tcpdump(1) typescript(2) vite(2) vscode(2) vue(8) vue-admin(2) vue3(1) webssh(1) xtermjs(1) xxl-job(1) yarn(1) zookeeper(1) 云原生(4) 云原生框架(1) 介绍(1) 单体架构->freemesh(1) 单元化(1) 博客(1) 压缩(1) 可观测(1) 后台管理系统(1) 命名规范(1) 多云多活(1) 如水网(1) 安全(1) 安装(1) 容器(2) 开发联调神器(1) 微前端(1) 微服务(2) 微服务架构->freemesh(1) 微服务框架(1) 快速开始(1) 控制面(1) 数据面(1) 文集(2) 服务发现(1) 服务网格(1) 流量泳道(1) 流量管理(1) 监控告警(1) 端口映射(1) 证书(1) 负载均衡(1) 配置(1)