微前端之实践应用间的全局状态管理、应用缓存和预加载子应用

编程入门 行业动态 更新时间:2024-10-23 07:33:51

微前端之实践应用间的全局状态管理、应用<a href=https://www.elefans.com/category/jswz/34/1771061.html style=缓存和预加载子应用"/>

微前端之实践应用间的全局状态管理、应用缓存和预加载子应用

一、微前端之实践应用间的全局状态管理、应用缓存和预加载子应用
  1. 全局状态管理,应用间的全局 store,如下所示:
  • micro 下的 storeindex.js,对外暴露 createStore,使用 store 管理 initDataobservers 管理所有的订阅者和依赖,通过 getStore 获取 store,通过 update 更新 store。当 store 发生变化,通知订阅者,执行 store 的操作,进行缓存,将 store 更新为 value,通知所有的订阅者,监听 store 的变化。subscribe 是添加订阅者,index.js,代码如下:
export const createStore = (initData = {}) => (() => { let store = initData; const observers = []; const getStore = () => store;const update = (value) => {if (value !== store) {const oldValue = store;store = value;observers.forEach(async item => await item(store, oldValue));}}const subscribe = (fn) => {observers.push(fn);}return {getStore,update,subscribe,}
})()
  • 在主应用 mainutilindex.js,通过 createStore 创建全局状态管理,以 getStore 获取到存的所有 store 数据。通过 window.storestore 挂载到 window 上,通过 store.subscribe 添加订阅者。通过 store.update 更新 store 数据,将之前的 store 数据和所要修改的数据进行合并修改,index.js,代码如下:
import { registerMicroApps, start, createStore } from '../../micro'
import { loading } from '../store'const store = createStore();
const storeData = store.getStore();
window.store = store;
store.subscribe((newValue, oldValue) => {console.log(newValue, oldValue, '---')
})
store.update({ ...storeData, a: 1 });export const registerApp = (list) => {registerMicroApps(list, {beforeLoad: [() => {loading.changeLoading(true)console.log('开始加载')}],mounted: [() => {loading.changeLoading(false)console.log('渲染完成')}],destoryed: [() => {console.log('卸载完成')}]})start()
}
  • vue3 子应用中的 main.js,在 mount 生命周期中,通过 window.store.getStore 获取到 store 里面的数据,通过 window.store.update 修改 store 里面的数据,main.js,代码如下:
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import { setMain } from './utils/global'let instance = null; 
function render() {instance = createApp(App);instance.use(router).mount('#app');
}if (!window.__MICRO_WEB__) {render();
}
export async function bootstrap() {console.log('vue3.0 app bootstrap');
}export async function mount(app) {setMain(app);// window.custom.emit('test1', {a: 1});// window.custom.on('test1', () => {//   window.custom.emit('test2', { b: 2 });// });const storeData = window.store.getStore();window.store.update({ ...storeData, a: 11 });render();
}export async function unmount(ctx) {instance.unmount();instance = null;const { container } = ctx;if (container) {document.querySelector(container).innerHTML = '';}
}
  1. 提高加载性能,应用缓存,如下所示:
  • micro 下的 loaderindex.js,在 parseHtml 解析 html 时,使用 cache,根据子应用的 name 来做缓存。通过 cache[name] 判断是否命中 name,使用缓存,返回对应的内容。同时,将 dom、allScript 直接缓存,后面可以直接使用 cache,获取到对应的子应用,代码如下:
const cache = {}; 
export const parseHtml = async (entry, name) => {if (cache[name]) {return cache[name];}const html = await fetchResource(entry);let allScript = [];const div = document.createElement('div');div.innerHTML = html;const [dom, scriptUrl, script] = await getResources(div, entry);const fetchedScripts = await Promise.all(scriptUrl.map(async item => fetchResource(item)));allScript = script.concat(fetchedScripts);cache[name] = [dom, allScript];return [dom, allScript];
}
  1. 提高加载性能,预加载子应用,如下所示:
  • micro 下的 loaderprefetch.js,在 prefetch 中,先获取到所有子应用列表,不包括当前正在显示的。然后,通过 Promise.all 预加载剩下的所有子应用,prefetch.js,代码如下:
import { getList } from '../const/subApps';
import { parseHtml } from './index';export const prefetch = async () => {const list = getList().filter(item => !window.location.pathname.startsWith(item.activeRule));await Promise.all(list.map(async item => await parseHtml(item.entry, item.name)));
}
  • micro 下的 start.js 中,通过 currentApp 渲染要加载的子应用,然后通过 prefetch 预加载剩下的所有子应用,但是不显示,代码如下:
import { setList, getList } from './const/subApps'
import { currentApp } from './utils'
import { rewriteRouter } from './router/rewriteRouter'
import { setMainLifecycle } from './const/mainLifeCycle'
import { prefetch } from './loader/prefetch'
import { Custom } from './customevent'const custom = new Custom();
custom.on('test', (data) => {console.log(data);
});
window.custom = custom;rewriteRouter();
export const registerMicroApps = (appList, lifeCycle) => {setList(appList);setMainLifecycle(lifeCycle);// window.appList = appList;
}export const start = () => {const apps = getList();if (!apps.length) {throw Error('子应用列表为空, 请正确注册');}const app = currentApp();const { pathname, hash } = window.location;if (!hash) {window.history.pushState(null, null, '/vue3#/index');}if (app && hash) {const url = pathname + hash;window.__CURRENT_SUB_APP__ = app.activeRule;window.history.pushState('', '', url);}prefetch();
}

更多推荐

微前端之实践应用间的全局状态管理、应用缓存和预加载子应用

本文发布于:2024-02-11 11:09:30,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1680663.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:缓存   全局   加载   状态

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!