互联网营销的方法有哪些优化网站找哪家
一、前言
在微前端架构中,状态管理是一个重要的课题。由于子应用是独立的,它们之间可能需要共享状态或通信。以下是基于
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
。