From dd7fc7810935301cd72e0b3c088cd4dfbb51637e Mon Sep 17 00:00:00 2001
From: bailicangdu <1264889788@qq.com>
Date: Fri, 10 Dec 2021 20:21:54 +0800
Subject: [PATCH] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E6=96=87=E6=A1=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
dev/children/react16/src/index.js | 46 +++++-----
docs/sidebar.md | 1 +
docs/zh-cn/configure.md | 8 ++
docs/zh-cn/data.md | 4 +-
docs/zh-cn/keep-alive.md | 142 ++++++++++++++++++++++++++++++
docs/zh-cn/life-cycles.md | 56 ++++++++----
6 files changed, 216 insertions(+), 41 deletions(-)
create mode 100644 docs/zh-cn/keep-alive.md
diff --git a/dev/children/react16/src/index.js b/dev/children/react16/src/index.js
index 0b6f67525..8212bc09e 100644
--- a/dev/children/react16/src/index.js
+++ b/dev/children/react16/src/index.js
@@ -1,12 +1,12 @@
-import "./public-path";
+import './public-path';
import 'babel-polyfill'
// import '@babel/polyfill'
-import React from "react";
-import ReactDOM from "react-dom";
-import "antd/dist/antd.css";
-import "./index.css";
-import Router from "./router";
-import { Modal, notification } from "antd";
+import React from 'react';
+import ReactDOM from 'react-dom';
+import 'antd/dist/antd.css';
+import './index.css';
+import Router from './router';
+import { Modal, notification } from 'antd';
import subMicroApp from '@micro-zoe/micro-app'
// 循环内嵌
@@ -16,9 +16,9 @@ subMicroApp.start({
// 数据监听
window.microApp?.addDataListener((data) => {
- console.log("react16 来自基座应用的数据", data)
+ console.log('react16 来自基座应用的数据', data)
notification.open({
- message: "来自基座应用的数据",
+ message: '来自基座应用的数据',
description: JSON.stringify(data),
duration: 1,
})
@@ -27,7 +27,7 @@ window.microApp?.addDataListener((data) => {
function handleGlobalData(data) {
console.log('react16: 来自全局数据')
Modal.info({
- title: "react16: 来自全局数据",
+ title: 'react16: 来自全局数据',
content: (
{JSON.stringify(data)}
@@ -41,7 +41,7 @@ function handleGlobalData(data) {
window.microApp?.addGlobalDataListener(handleGlobalData);
// 监听keep-alive模式下的app状态
-window.addEventListener("appstate-change", function (e) {
+window.addEventListener('appstate-change', function (e) {
console.log('子应用内部console.log -- keep-alive app 状态:', e.detail.appState);
})
@@ -50,16 +50,16 @@ ReactDOM.render(
,
- document.getElementById("root")
+ document.getElementById('root')
);
// 监听卸载
-window.addEventListener("unmount", function () {
- ReactDOM.unmountComponentAtNode(document.getElementById("root"));
- console.log("微应用react16卸载了 -- 自定义事件unmount");
+window.addEventListener('unmount', function () {
+ ReactDOM.unmountComponentAtNode(document.getElementById('root'));
+ console.log('微应用react16卸载了 -- 自定义事件unmount');
})
-console.timeEnd("react#16");
+console.timeEnd('react#16');
// ----------------------分割线-umd模式--------------------- //
// function mount () {
@@ -67,18 +67,18 @@ console.timeEnd("react#16");
//
//
// ,
-// document.getElementById("root")
+// document.getElementById('root')
// );
-// console.log("微应用react16渲染了 -- 来自umd-mount");
-// console.timeEnd("react#16");
+// console.log('微应用react16渲染了 -- 来自umd-mount');
+// console.timeEnd('react#16');
// }
// function unmount () {
-// console.log("微应用react16卸载了 -- 来自umd-unmount");
+// console.log('微应用react16卸载了 -- 来自umd-unmount');
// // 卸载时关闭弹窗
// notification.destroy()
// // 卸载应用
-// ReactDOM.unmountComponentAtNode(document.getElementById("root"));
+// ReactDOM.unmountComponentAtNode(document.getElementById('root'));
// }
// // 微前端环境下,注册mount和unmount方法
@@ -109,7 +109,7 @@ console.timeEnd("react#16");
// const dynamicScript1 = document.createElement('script')
// // dynamicScript1.setAttribute('type', 'module')
-// // dynamicScript1.textContent = 'console.warn("inline module")'
+// // dynamicScript1.textContent = 'console.warn('inline module')'
// dynamicScript1.setAttribute('src', 'http://127.0.0.1:8080/test.js')
// dynamicScript1.onload = () => {
// console.log('动态module加载完成了')
@@ -136,7 +136,7 @@ console.timeEnd("react#16");
//
// `
-// const doc = parser.parseFromString(htmlString, "text/html")
+// const doc = parser.parseFromString(htmlString, 'text/html')
// console.log(
// 'DOMParser querySelector',
diff --git a/docs/sidebar.md b/docs/sidebar.md
index 8c86b9999..2ccc42ba4 100755
--- a/docs/sidebar.md
+++ b/docs/sidebar.md
@@ -14,6 +14,7 @@
- [预加载](zh-cn/prefetch)
- [插件系统](zh-cn/plugins)
- [多层嵌套](zh-cn/nest)
+ - [keep-alive](zh-cn/keep-alive)
- [高级功能](zh-cn/advanced)
- [API](zh-cn/api)
- [路由](zh-cn/route)
diff --git a/docs/zh-cn/configure.md b/docs/zh-cn/configure.md
index 18cb109f0..6cea666d5 100644
--- a/docs/zh-cn/configure.md
+++ b/docs/zh-cn/configure.md
@@ -101,6 +101,14 @@ shadowDOM具有更强的样式隔离能力,开启后,``标签会
当子应用是ssr应用时,需要设置ssr属性,此时micro-app会根据ssr模式加载子应用。
+## keep-alive
+- Desc: `是否开启keep-alive模式`
+- Type: `string(boolean)`
+- Default: `false`
+- 使用方式: ``
+
+开启keep-alive后,应用卸载时会进入缓存,而不是销毁它们,以便保留应用的状态和提升重复渲染的性能。
+
## 全局配置
全局配置会影响每一个子应用,请小心使用!
diff --git a/docs/zh-cn/data.md b/docs/zh-cn/data.md
index 6c25a749c..50af716d1 100644
--- a/docs/zh-cn/data.md
+++ b/docs/zh-cn/data.md
@@ -90,6 +90,7 @@ export default {
}
}
}
+
```
@@ -146,8 +147,8 @@ vue中监听方式和普通事件一致。
@datachange='handleDataChange'
/>
-
```
diff --git a/docs/zh-cn/keep-alive.md b/docs/zh-cn/keep-alive.md
new file mode 100644
index 000000000..c5a594945
--- /dev/null
+++ b/docs/zh-cn/keep-alive.md
@@ -0,0 +1,142 @@
+在应用之间切换时,你有时会想保留这些应用的状态,以便恢复用户的操作行为和提升重复渲染的性能,此时开启keep-alive模式可以达到这样的效果。
+
+开启keep-alive后,应用卸载时不会销毁,而是推入后台运行。
+
+## 使用方式
+```html
+
+```
+
+## 生命周期
+keep-alive模式与普通模式最大的不同是生命周期,因为它不会被真正的卸载,也就不会触发 `unmount` 事件。
+
+在基座和子应用中的生命周期如下:
+
+### 基座应用
+
+#### 1. created
+``标签初始化后,加载资源前触发。
+
+#### 2. beforemount
+加载资源完成后,开始渲染之前触发`(只在初始化时执行一次)`。
+
+#### 3. mounted
+子应用渲染结束后触发`(只在初始化时执行一次)`。
+
+#### 4. error
+子应用渲染出错时触发,只有会导致渲染终止的错误才会触发此生命周期。
+
+#### 5. afterhidden
+子应用卸载时触发。
+
+#### 6. beforeshow
+子应用再次渲染之前触发`(初始化时不执行)`。
+
+#### 7. aftershow
+子应用再次渲染之后触发`(初始化时不执行)`。
+
+
+#### 监听生命周期
+
+
+#### ** React **
+因为React不支持自定义事件,所以我们需要引入一个polyfill。
+
+`在标签所在的文件顶部`添加polyfill,注释也要复制。
+```js
+/** @jsxRuntime classic */
+/** @jsx jsxCustomEvent */
+import jsxCustomEvent from '@micro-zoe/micro-app/polyfill/jsx-custom-event'
+```
+
+**开始使用**
+```js
+ console.log('micro-app元素被创建')}
+ onBeforemount={() => console.log('即将被渲染,只在初始化时执行一次')}
+ onMounted={() => console.log('已经渲染完成,只在初始化时执行一次')}
+ onAfterhidden={() => console.log('已卸载')}
+ onBeforeshow={() => console.log('即将重新渲染,初始化时不执行')}
+ onAftershow={() => console.log('已经重新渲染,初始化时不执行')}
+ onError={() => console.log('渲染出错')}
+/>
+```
+
+#### ** Vue **
+vue中监听方式和普通事件一致。
+```html
+
+
+
+
+
+```
+
+
+### 子应用
+keep-alive模式下,在子应用卸载、重新渲染时,micro-app都会向子应用发送名为`appstate-change`的自定义事件,子应用可以通过监听该事件获取当前状态,状态值可以通过事件对象属性`e.detail.appState`获取。
+
+`e.detail.appState`的值有三个:afterhidden、beforeshow、aftershow,分别对应卸载、即将渲染、已经渲染。
+
+```js
+// 监听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、再次渲染时url和页面不匹配
+keep-alive的应用在卸载时会保留页面状态,再次渲染时直接恢复,当应用再次渲染时的url与离开时不一致,则出现url和页面不匹配的问题。
+
+如果这个问题对你造成了困扰,可以通过监听`appstate-change`事件,在`beforeshow`时进行修复,根据url跳转对应的页面。
+
+#### 2、如何恢复页面滚动位置?
+micro-app不会记录页面滚动位置,应用再次渲染时也不会进行恢复,需要开发者进行记录和恢复。
diff --git a/docs/zh-cn/life-cycles.md b/docs/zh-cn/life-cycles.md
index 6fe4ff106..d8a62c959 100644
--- a/docs/zh-cn/life-cycles.md
+++ b/docs/zh-cn/life-cycles.md
@@ -3,24 +3,22 @@
## 生命周期列表
#### 1. created
-在``标签初始化后,加载资源前触发。
+``标签初始化后,加载资源前触发。
#### 2. beforemount
-在加载资源完成后,开始渲染之前触发。
+加载资源完成后,开始渲染之前触发。
#### 3. mounted
-在子应用渲染结束后触发。
+子应用渲染结束后触发。
#### 4. unmount
-在子应用被卸载时触发。
+子应用卸载时触发。
#### 5. error
子应用渲染出错时触发,只有会导致渲染终止的错误才会触发此生命周期。
## 监听生命周期
-我们通过micro-app元素的自定义事件发送生命周期。
-
#### ** React **
@@ -41,23 +39,47 @@ import jsxCustomEvent from '@micro-zoe/micro-app/polyfill/jsx-custom-event'
onCreated={() => console.log('micro-app元素被创建')}
onBeforemount={() => console.log('即将被渲染')}
onMounted={() => console.log('已经渲染完成')}
- onUnmount={() => console.log('被卸载')}
+ onUnmount={() => console.log('已经卸载')}
onError={() => console.log('渲染出错')}
/>
```
#### ** Vue **
vue中监听方式和普通事件一致。
-```vue
-
+```html
+
+
+
+
+
```
#### ** 自定义 **
我们可以手动监听生命周期事件。