keep-alive

在应用之间切换时,我们有时会想保留这些应用的状态,以便恢复用户的操作行为和提升重复渲染的性能,此时开启keep-alive模式可以达到这样的效果。

开启keep-alive后,应用卸载时不会销毁,而是推入后台运行。

使用方式

<micro-app name='xx' url='xx' keep-alive></micro-app>

生命周期

keep-alive模式与普通模式最大的不同是生命周期,因为它不会被真正的卸载,也就不会触发 unmount 事件。

生命周期如下:

主应用

1. created

<micro-app>标签初始化后,加载资源前触发。

2. beforemount

加载资源完成后,开始渲染之前触发(只在初始化时执行一次)

3. mounted

子应用渲染结束后触发(只在初始化时执行一次)

4. error

子应用渲染出错时触发,只有会导致渲染终止的错误才会触发此生命周期。

5. afterhidden

子应用推入后台时触发。

6. beforeshow

子应用推入前台之前触发(初始化时不执行)

7. aftershow

子应用推入前台之后触发(初始化时不执行)

监听生命周期

React
Vue

因为React不支持自定义事件,所以我们需要引入一个polyfill。

在<micro-app>标签所在的文件顶部添加polyfill,注释也要复制。

/** @jsxRuntime classic */
/** @jsx jsxCustomEvent */
import jsxCustomEvent from '@micro-zoe/micro-app/polyfill/jsx-custom-event'

开始使用

<micro-app
  name='xx'
  url='xx'
  onCreated={() => console.log('micro-app元素被创建')}
  onBeforemount={() => console.log('即将被渲染,只在初始化时执行一次')}
  onMounted={() => console.log('已经渲染完成,只在初始化时执行一次')}
  onAfterhidden={() => console.log('已推入后台')}
  onBeforeshow={() => console.log('即将推入前台,初始化时不执行')}
  onAftershow={() => console.log('已经推入前台,初始化时不执行')}
  onError={() => console.log('渲染出错')}
/>

vue中监听方式和普通事件一致。

<template>
  <micro-app
    name='xx'
    url='xx'
    @created='created'
    @beforemount='beforemount'
    @mounted='mounted'
    @afterhidden='afterhidden'
    @beforeshow='beforeshow'
    @aftershow='aftershow'
    @error='error'
  />
</template>

<script>
export default {
  methods: {
    created () {
      console.log('micro-app元素被创建'),
    },
    beforemount () {
      console.log('即将被渲染,只在初始化时执行一次'),
    },
    mounted () {
      console.log('已经渲染完成,只在初始化时执行一次'),
    },
    afterhidden () {
      console.log('已推入后台'),
    },
    beforeshow () {
      console.log('即将推入前台,初始化时不执行'),
    },
    aftershow () {
      console.log('已经推入前台,初始化时不执行'),
    },
    error () {
      console.log('渲染出错'),
    }
  }
}
</script>

子应用

keep-alive模式下,在子应用卸载、重新渲染时,micro-app都会向子应用发送名为appstate-change的自定义事件,子应用可以通过监听该事件获取当前状态,状态值可以通过事件对象属性e.detail.appState获取。

e.detail.appState的值有三个:afterhidden、beforeshow、aftershow,分别对应卸载、即将渲染、已经渲染。

// 监听keep-alive模式下的应用状态
window.addEventListener('appstate-change', function (e) {
  if (e.detail.appState === 'afterhidden') {
    console.log('已卸载')
  } else if (e.detail.appState === 'beforeshow') {
    console.log('即将重新渲染')
  } else if (e.detail.appState === 'aftershow') {
    console.log('已经重新渲染')
  }
})

应用初始化时不会触发appstate-change事件。

常见问题

1、如何恢复页面滚动位置?

micro-app不会记录页面滚动位置,应用再次渲染时也不会进行恢复,需要开发者进行记录和恢复。

2、子应用内部页面切换后状态丢失

micro-app的keep-alive是应用级别的,它只会保留当前正在活动的页面状态,如果想要缓存具体的页面或组件,需要使用子应用框架的能力,如:vue的keep-alive。