Vite+微前端Qiankun-状态管理
一、前言
在微前端架构中,状态管理是一个重要的课题。由于子应用是独立的,它们之间可能需要共享状态或通信。以下是基于
qiankun微前端架构的状态管理方案,结合Vue 3和Vite的实现。
二、状态管理方案
在微前端中,状态管理可以分为以下几种方式:
1. 主应用和子应用共享状态:
- 通过全局状态管理库(如
Pinia或Vuex)在主应用中管理全局状态,子应用通过主应用提供的接口访问或修改状态。 - 使用
qiankun的initGlobalState方法实现主应用和子应用之间的状态共享。
2. 子应用独立状态管理:
- 每个子应用使用自己的状态管理库(如
Pinia或Vuex),状态独立管理,不与其他子应用共享。
3. 事件通信:
- 使用
CustomEvent或EventBus实现子应用之间的通信。
三、使用 qiankun 的 initGlobalState 实现状态共享
qiankun提供了initGlobalState方法,用于在主应用和子应用之间共享状态。
1. 主应用配置
在主应用中初始化全局状态。
// src/main.ts
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import { registerMicroApps, start, initGlobalState } from 'qiankun';const app = createApp(App);
app.use(router);
app.mount('#app');// 初始化全局状态
const initialState = {user: {name: 'Main App User',},
};const actions = initGlobalState(initialState);// 监听状态变化
actions.onGlobalStateChange((state, prevState) => {console.log('主应用:状态变化', state, prevState);
});// 注册子应用
registerMicroApps([{name: 'subApp1',entry: '//localhost:7101',container: '#subapp-container',activeRule: '/subApp1',},{name: 'subApp2',entry: '//localhost:7102',container: '#subapp-container',activeRule: '/subApp2',},
]);// 启动 qiankun
start();
2. 子应用配置
在子应用中获取和修改全局状态。
// subApp1/src/main.ts
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';let instance = null;function render(props = {}) {const { container } = props;instance = createApp(App);instance.use(router);instance.mount(container ? container.querySelector('#app') : '#app');// 获取全局状态if (props.onGlobalStateChange && props.setGlobalState) {props.onGlobalStateChange((state, prevState) => {console.log('子应用1:状态变化', state, prevState);});// 修改全局状态props.setGlobalState({user: {name: 'SubApp1 User',},});}// 将 props 注入到 Vue 实例中instance.provide('MAIN_APP_PROPS', props);
}if (!window.__POWERED_BY_QIANKUN__) {render();
}export async function bootstrap() {console.log('subApp1 bootstrap');
}export async function mount(props) {console.log('subApp1 mount');render(props);
}export async function unmount() {console.log('subApp1 unmount');instance.unmount();instance = null;
}
3. Vue实例中修改全局变量
在配置中已经将主应用传过来的prop对象参数,使用依赖注入的方式注入到全局
instance.provide('MAIN_APP_PROPS', props);
vue实例中可以使用inject获取这个参数,从而使用prop参数里面带的onGlobalStateChange、setGlobalState两个函数管理全局状态
/**
* test.vue TODO
* @Author ZhangJun
* @Date 2025/3/12 15:03
**/
<template><el-card class="text-left"><template #header><div>子应用1测试修改全局状态</div></template><div><div>当前全局状态:</div><div class="bg-blue-lighter"><el-inputv-model="globalStateCache"style="width: 240px":autosize="{ minRows: 2, maxRows: 4 }"type="textarea"placeholder="请输入新的全局状态"/></div></div><el-button style="margin-top: 10px" type="primary" @click="changeGlobalState()">修改全局状态</el-button></el-card>
</template><script setup lang="ts">
import {inject, ref} from "vue";const mainAppProps:any = inject('MAIN_APP_PROPS')//全局状态缓存
const globalStateCache = ref('')//监听全局状态变化
mainAppProps?.onGlobalStateChange((state:any,prev:any) => {if(JSON.stringify(state)!== JSON.stringify(prev)){globalStateCache.value = JSON.stringify(state)}
})/*** 全局状态的修改*/
const changeGlobalState = () => {let updateState = JSON.parse(globalStateCache.value)//更新全局状态mainAppProps?.setGlobalState(updateState)
}</script><style scoped>
.bg-blue-lighter{background-color: #f0f9ff;color: #4a4a4a;
}
</style>
四、使用 Pinia 实现子应用独立状态管理
如果子应用需要独立管理状态,可以使用Pinia(推荐)或Vuex。
1. 安装 Pinia
在子应用中安装Pinia:
npm install pinia
2. 配置 Pinia
在子应用中创建Pinia实例并注入到应用中。
// subApp1/src/main.ts
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
import router from './router';let instance = null;function render(props = {}) {const { container } = props;const app = createApp(App);const pinia = createPinia();app.use(pinia);app.use(router);instance = app.mount(container ? container.querySelector('#app') : '#app');
}if (!window.__POWERED_BY_QIANKUN__) {render();
}export async function bootstrap() {console.log('subApp1 bootstrap');
}export async function mount(props) {console.log('subApp1 mount');render(props);
}export async function unmount() {console.log('subApp1 unmount');instance.unmount();instance = null;
}
3. 创建 Pinia Store
在子应用中创建Pinia Store。
// subApp1/src/stores/userStore.js
import { defineStore } from 'pinia';export const useUserStore = defineStore('user', {state: () => ({name: 'SubApp1 User',}),actions: {updateName(newName) {this.name = newName;},},
});
4. 在组件中使用 Pinia Store
<!-- subApp1/src/App.vue -->
<template><div><h1>{{ userStore.name }}</h1><button @click="updateName">Update Name</button></div>
</template><script>
import { useUserStore } from './stores/userStore';export default {setup() {const userStore = useUserStore();const updateName = () => {userStore.updateName('New SubApp1 User');};return {userStore,updateName,};},
};
</script>
五、使用 EventBus 实现子应用通信
如果子应用之间需要通信,可以使用EventBus。
在主应用中创建一个全局事件总线,并将其注入到子应用中。
1. 创建 EventBus
在主应用中创建一个eventBus.js文件,用于导出事件总线实例。
// src/eventBus.js
import mitt from 'mitt'
const eventBus = mitt()
export default eventBus;
2. 主应用注入事件总线
在主应用中,通过registerMicroApps的props参数将事件总线传递给子应用。
// src/main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import { registerMicroApps, start } from 'qiankun';
import eventBus from './eventBus';const app = createApp(App);
app.use(router);
app.mount('#app');// 注册子应用
registerMicroApps([{name: 'subApp1',entry: '//localhost:7101',container: '#subapp-container',activeRule: '/subApp1',props: {eventBus, // 将事件总线传递给子应用},},{name: 'subApp2',entry: '//localhost:7102',container: '#subapp-container',activeRule: '/subApp2',props: {eventBus, // 将事件总线传递给子应用},},
]);// 启动 qiankun
start();
3. 在子应用中使用 EventBus
在子应用中,通过props获取事件总线,并使用它来发送和接收事件。
3.1 子应用1 发送事件
在子应用1中,通过事件总线发送事件。
<!-- subApp1/src/views/Home.vue -->
<template><div><h1>子应用1</h1><button @click="sendMessage">发送消息</button></div>
</template><script>
import { inject } from 'vue';export default {setup() {const props = inject('props');const eventBus = props.eventBus;const sendMessage = () => {eventBus.emit('message-from-subApp1', {message: 'Hello from SubApp1',});};return {sendMessage,};},
};
</script>
3.2 子应用2 监听事件
在子应用2中,通过事件总线监听事件。
<!-- subApp2/src/views/Home.vue -->
<template><div><h1>子应用2</h1><p>收到消息:{{ message }}</p></div>
</template><script>
import { inject, ref, onMounted, onUnmounted } from 'vue';export default {setup() {const props = inject('props');const eventBus = props.eventBus;const message = ref('');const handleMessage = (payload) => {message.value = payload.message;};onMounted(() => {eventBus.on('message-from-subApp1', handleMessage);});onUnmounted(() => {eventBus.off('message-from-subApp1', handleMessage);});return {message,};},
};
</script>
六、总结
- 全局状态共享:使用
qiankun的initGlobalState方法。 - 子应用独立状态管理:使用
Pinia或Vuex。 - 子应用通信:使用
EventBus或CustomEvent。
相关文章:
Vite+微前端Qiankun-状态管理
一、前言 在微前端架构中,状态管理是一个重要的课题。由于子应用是独立的,它们之间可能需要共享状态或通信。以下是基于qiankun微前端架构的状态管理方案,结合Vue 3和Vite的实现。 二、状态管理方案 在微前端中,状态管理可以分为…...
【初学者】Python语言中有没有指针类型?
李升伟 整理 在Python语言中,没有像C或C那样的显式指针类型。Python的设计哲学强调简洁和易读,因此它隐藏了许多底层的细节,包括指针。 不过,Python中的变量可以被视为对对象的引用。当你创建一个对象并将其赋值给一个变量时&am…...
网络编程---多客户端服务器
写一个服务器和两个客户端 运行服务器和2个客户端,实现聊天功能 客户端1 和 客户端2 进行聊天 客户端1将聊天数据发送给服务器 服务器将聊天数据转发给客户端2 要求: 服务器使用 select 模型实现 客户端1使用 poll 模型实现 客户端2使用 多线程实现…...
SPACE_GAME
以下是一些關於星際遊戲的 GitHub 代碼範本,您可以根據需求進行修改或擴展。這裡提供一個簡單的 Python 代碼範例,展示如何創建一個簡單的星際遊戲框架。 專案結構 space_game/ ├── main.py ├── spaceship.py ├── enemy.py └── README.md1…...
Web Component 教程(五):从 Lit-html 到 LitElement,简化组件开发
前言 在现代前端开发中,Web 组件是一种非常流行的技术,它允许我们创建可重用的、自包含的 UI 元素。而 Lit-html 是一个简洁高效库,用于在 Web 组件中进行渲染。在这篇教程中,我们一步步学习如何 Lit-html 来创建 Web Component。…...
Vue3:构建高效用户界面的利器
一、Vue.js 简介 Vue.js(读音 /vjuː/, 类似于 view)是一套构建用户界面的渐进式框架。它只关注视图层,采用自底向上增量开发的设计。Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件 ,学习起来非常简单…...
LeetCode 2614.对角线上的质数:遍历(质数判断)
【LetMeFly】2614.对角线上的质数:遍历(质数判断) 力扣题目链接:https://leetcode.cn/problems/prime-in-diagonal/ 给你一个下标从 0 开始的二维整数数组 nums 。 返回位于 nums 至少一条 对角线 上的最大 质数 。如果任一对角线上均不存在质数&…...
红日靶场(二)——个人笔记
靶场搭建 新增VMnet2网卡 **web:**需要配置两张网卡,分别是外网出访NAT模式和内网域环境仅主机模式下的VMnet2网卡。 **PC:**跟web一样,也是需要配置两张网卡,分别是外网出访NAT模式和内网域环境仅主机模式下的VMn…...
实时视频分析的破局之道:蓝耘 MaaS 如何与海螺 AI 视频实现高效协同
一、蓝耘 MaaS 平台:AI 模型全生命周期管理的智能引擎 蓝耘 MaaS(Model-as-a-Service)平台是由蓝耘科技推出的 AI 模型全生命周期管理平台,专注于为企业和开发者提供从模型训练、推理到部署的一站式解决方案。依托云原生架构、高…...
清晰易懂的 Swift 安装与配置教程
初学者也能看懂的 Swift 安装与配置教程 本教程将手把手教你如何在 macOS 系统上安装 Swift,配置依赖包缓存位置,并指出新手容易踩坑的细节。即使你是零基础小白,也能快速上手! 一、安装 Swift(macOS 环境)…...
大数据 ETL 异常值缺失值处理完整方案
在大数据时代,数据已成为推动业务创新与决策优化的重要资产。然而,数据的海量、异构及实时性往往伴随着噪声、错误记录以及缺失现象,严重影响下游分析模型的准确性和可靠性。尤其在 ETL(抽取、转换、加载)环节中,如何在海量数据流中迅速甄别并处理异常数据,便成为决定整…...
macOS homebrew - 切换源
https://mirrors.tuna.tsinghua.edu.cn/help/homebrew/ 环境变量中 添加: export HOMEBREW_BREW_GIT_REMOTE"https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git" export HOMEBREW_CORE_GIT_REMOTE"https://mirrors.tuna.tsinghua.edu.cn…...
如何基于Gone编写一个Goner对接Apollo配置中心(下)—— 对组件进行单元测试
项目地址:https://github.com/gone-io/gone 原文地址:https://github.com/gone-io/goner/blob/main/docs/test_goner.md 本文介绍的例子,代码在:https://github.com/gone-io/goner/blob/main/apollo 文章目录 引言编写“可测试”的…...
走进Java:String字符串的基本使用
❀❀❀ 大佬求个关注吧~祝您开心每一天 ❀❀❀ 目录 一、什么是String 二、如何定义一个String 1. 用双引号定义 2. 通过构造函数定义 三、String中的一些常用方法 1 字符串比较 1.1 字符串使用 1.2 字符串使用equals() 1.3 使用 equalsIgnoreCase() 1.4 cpmpareTo…...
python系列之元组(Tuple)
不为失败找理由,只为成功找方法。所有的不甘,因为还心存梦想,所以在你放弃之前,好好拼一把,只怕心老,不怕路长。 python系列之元组(Turple) 一、元组是什么?——给新手的…...
破解验证码新利器:基于百度OCR与captcha-killer-modified插件的免费调用教程
破解验证码新利器:基于百度OCR与captcha-killer-modified插件的免费调用教程 引言 免责声明: 本文提供的信息仅供参考,不承担因操作产生的任何损失。读者需自行判断内容适用性,并遵守法律法规。作者不鼓励非法行为,保…...
批量删除 PPT 中的所有图片、某张指定图片或者所有二维码图片
PPT 文档中的图片如何删除呢?相信很多小伙伴或碰到类似的需求。比如我们需要删除 PPT 文档中的某一张图片或者某张二维码图片,如果每一页都有这张图片,或者有很多 ppt 都有同一张要删除的图片,我们应该怎么快速的完成删除呢&#…...
大模型开发(六):LoRA项目——新媒体评论智能分类与信息抽取系统
LoRA项目——新媒体评论智能分类与信息抽取系统 0 前言1 项目介绍1.1 项目功能1.2 技术原理1.3 软硬件环境1.4 项目结构 2 数据介绍与处理2.1 数据集介绍2.2 数据处理2.3 数据导入器 3 模型训练3.1 配置文件3.2 工具函数3.3 模型训练3.4 模型评估 4 模型推理 0 前言 微调里面&…...
mysql-innodb存储引擎主键索引叶子结点数据结构(非单纯的双向链表)
我们应该清楚行记录是放在页中的。 compact行记录格式: 主要介绍几个比较重要的参数 heap_no: 页号 record_type: 0 表示普通类型(叶子结点),1表示B树的非叶子节点 ,2 表示最小记录ÿ…...
MySQL 进阶学习文档
一、存储引擎 1.1 核心架构 四层架构:连接层 → 服务层 → 引擎层 → 存储层插件式存储引擎:不同引擎独立管理数据存储,可动态选择 1.2 主流引擎对比 特性InnoDB(默认)MyISAMMemory事务支持✅ 支持❌ 不支持❌ 不支…...
物联网为什么用MQTT不用 HTTP 或 UDP?
先来两个代码对比,上传温度数据给服务器。 MQTT代码示例 // MQTT 客户端连接到 MQTT 服务器 mqttClient.connect("mqtt://broker.server.com:8883", clientId) // 订阅特定主题 mqttClient.subscribe("sensor/data", qos1) // …...
Vmware中的centos7连接上网
有很多刚刚开始配置了centos7,然后发现不能上网现在来解决这个问题。 测试能不能上网 先还原这个设置,如果没有动过的话就不用,连接模式是NAT模式 然后进去设置网络环境,记得是用超级用户设置 vi /etc/sysconfig/network-script…...
【AI知识】常见的优化器及其原理:梯度下降、动量梯度下降、AdaGrad、RMSProp、Adam、AdamW
常见的优化器 梯度下降(Gradient Descent, GD)局部最小值、全局最小值和鞍点凸函数和非凸函数动量梯度下降(Momentum)自适应学习率优化器AdaGrad(Adaptive Gradient Algorithm)RMSProp(Root M…...
线性规划的标准形式
标准形式的定义 目标函数:最大化线性目标函数 其中,x 是决策变量向量,c 是目标系数向量。 约束条件:等式形式约束 A x b, 其中,A 是约束系数矩阵,b 是常数项向量。 变量非负约束: 。 因此…...
网络安全应急入门到实战
奇安信:95015网络安全应急响应分析报告(2022-2024年)官网可以下载 https://github.com/Bypass007/Emergency-Response-Notes 应急响应实战笔记 网络安全应急响应技术实战指南 .pdf 常见场景 第4章 勒索病毒网络安全应急响应 第5章 挖矿木…...
应用程序安全趋势:左移安全、人工智能和开源恶意软件
软件是大多数行业业务运营的核心,这意味着应用程序安全从未如此重要。 随着组织采用云原生架构、微服务和开源组件,攻击面不断扩大。结果是:攻击者渴望利用的易受攻击和恶意依赖项数量不断增加。 2025 年,安全团队将面临日益复杂…...
ospf动态路由
一、为什么使用动态路由 OSPF(open shortest path first开放最短路径优先)是内部网关协议(IGP)的一种,基于链路状态算法(LS)。 OSPF企业级路由协议(RFC2328 OSPFv2),核心重点协议 OSPF共三个版本,OSPFV1主要是实验室…...
【视频】OrinNX+Ubuntu20.04:移植OpenCV-4.11.0 with CUDA(含opencv_contrib )
1、源码下载 github下载地址如下,选择最新版本4.11 https://github.com/opencv/opencv/releases/tag/4.11.0 https://github.com/opencv/opencv_contrib/releases/tag/4.11.02、安装依赖库 1)对图片编码格式的支持 sudo apt install zlib1g-dev libjpeg8-dev libwebp-dev…...
基于单片机控制的电动汽车双闭环调速系统(论文+源码)
2.1系统方案 在本次设计中,其系统整个框图如下图3.1所示,其主要的核心控制模块由电源供电模块,晶振电路,驱动电路模块,霍尔传感器,按键模块,复位电路,LCD液晶显示及直流电机等组成。…...
【病毒分析】伪造微软官网+勒索加密+支付威胁,CTF中勒索病毒解密题目真实还原!
1.背景 该CTF挑战题目完整复现了黑客的攻击链路,攻击者通过伪造钓鱼页面引导受害者下载恶意软件。用户访问伪造的 Microsoft 365 官网后,在点击“Windows Installer (64-bit)”下载选项时,页面会自动跳转至伪造的 GitHub 项目链接࿰…...
