除了主子应用的生命周期外,微前端也有自己的生命周期。本文将分别介绍微前端生命周期的执行时机以及微前端生命周期的勾子函数。
执行时机
在文章 微前端之注册子应用与路由拦截 中介绍路由拦截的时候,提到过 turnApp
函数,当时只是简单的打印了一行 log。
js
export const turnApp = async () => {
if (isTurnChild()) {
console.log('路由切换了');
}
}
其实微前端的生命周期就是在这里执行的,入口函数是 lifeCycle
。
js
export const turnApp = async () => {
if (isTurnChild()) {
// 微前端的生命周期执行
await lifeCycle()
}
}
勾子函数
在介绍勾子函数之前,让我们先对 isTurnChild
函数做个小修改。主要是添加了全局变量 __ORIGIN_APP__
来保存跳转前的上一个子应用。
js
// 子应用是否做了切换
export const isTurnChild = () => {
// __ORIGIN_APP__ 上一个子应用
// __CURRENT_SUB_APP__ 要跳转到的子应用
window.__ORIGIN_APP__ = window.__CURRENT_SUB_APP__
if (window.__CURRENT_SUB_APP__ === window.location.pathname) {
return false
}
const currentApp = window.location.pathname.match(/(\/\w+)/) // /vue3 /react15
if (!currentApp) return
window.__CURRENT_SUB_APP__ = currentApp[0]
return true
}
接着重点看下 lifeCycle
函数的实现。
js
// 类比 currentApp 函数,只不过筛选方式不同,一个是 pathname,一个是路由
export const findAppByRoute = (router) => {
return filterApp('activeRule', router)
}
export const lifeCycle = async () => {
// 获取到上一个子应用
const prevApp = findAppByRoute(window.__ORIGIN_APP__)
// 获取到要跳转到的子应用
const nextApp = findAppByRoute(window.__CURRENT_SUB_APP__)
if (!nextApp) return
if (prevApp && prevApp.destroyed) {
await destroyed(prevApp)
}
const app = beforeLoad(nextApp)
await mounted(app)
}
lifeCycle
函数主要做两件事情:
- 销毁上一个子应用
- 加载要跳转到的子应用
从代码中不难发现微前端有三个生命周期勾子函数:
beforeLoad
js
export const runMainLifeCycle = async (type) => {
const mainLife = getMainLifeCycle()
await Promise.all(mainLife[type].map(async item => await item()))
}
// 微前端生命周期-beforeLoad
export const beforeLoad = async (app) => {
// 对应的执行主应用的生命周期
await runMainLifeCycle('beforeLoad')
app && app.beforeLoad && app.beforeLoad()
const appContext = null
return appContext
}
mounted
js
// 微前端生命周期-mounted
export const mounted = async (app) => {
app && app.mounted && app.mounted()
// 对应的执行主应用的生命周期
await runMainLifeCycle('mounted')
}
destroyed
js
// 微前端生命周期-mounted
export const destroyed = async (app) => {
app && app.destroyed && app.destroyed()
// 对应的执行主应用的生命周期
await runMainLifeCycle('destroyed')
}