Match-id-06a032e63a37a939ac11e0d3f94647bd2122360c

This commit is contained in:
* 2022-04-27 10:32:19 +08:00 committed by *
parent 58d5869a58
commit 0043761609
2 changed files with 31 additions and 12 deletions

View File

@ -47,6 +47,9 @@ sequenceDiagram
```
## 传输数据结构
**<font color=#8B0000>限制chrome.runtime.sendMessage只能传递 JSON-serializable 数据</font>**
```ts
type passData = {
type: 'HORIZON_DEV_TOOLS',
@ -58,11 +61,22 @@ type passData = {
```
## horizon和devTools的主要交互
- 页面初始渲染
- 页面更新
- 页面销毁
- App初始渲染
- App更新
- App销毁
- 整个页面刷新
- devTools触发组件属性更新
## 对 hook 类型的判断和值的获取
Horizon 是一个底层框架,在 Horizon 与插件的交互过程中,我们不希望 Horizon 额外的增加一些代码和接口给插件使用,这可能会影响到 Horizon 的性能。
所以我们决定直接感知 hook 的属性值,通过其属性值判断 hook 类型,并直接调用 Reducer 的 trigger 函数触发更新。
## 触发组件更新方式
- 类组件的state调用实例的 setState 函数触发更新
- 类组件的props浅复制props后更新props值并调用 forceUpdate 触发更新
- 函数组件的props
- 函数组件的state调用 useState 函数触发更新
## VNode的清理
全局 hook 中保存了root VNode在解析 VNode 树的时候也会保存 VNode 的引用在清理VNode的时候这些 VNode 的引用也需要删除。
@ -73,7 +87,7 @@ type passData = {
- 通过解析 path 值可以分析出组件树的结构
## 组件props/state/hook等数据的传输和解析
将数据格式进行转换后进行传递。对于 props 和 类组件的 state他们都是对象可以将对象进行解析然后以 k-v 的形式,树的结构显示。函数组件的 Hooks 是以数组的形式存储在 vNode 的属性中的,每个 hook 的唯一标识符是 hIndex 属性值,在对象展示的时候不能展示该属性值,需要根据 hook 类型展示一个 state/ref/effect 等值。hook 中存储的值也可能不是对象,只是一个简单的字符串,他们的解析和 props/state 的解析同样存在差异。
将数据格式进行转换后进行传递。对于 props 和 类组件的 state他们都是对象可以将对象进行解析然后以 k-v 的形式,树的结构显示。函数组件的 Hooks 是以数组的形式存储在 vNode 的属性中的,每个 hook 的唯一标识符是 hIndex 属性值,在对象展示的时候不能展示该属性值,需要根据 hook 类型展示一个 state/ref/effect 等值。hook 中存储的值也可能不是对象,只是一个简单的字符串或者 dom 元素,他们的解析和 props/state 的解析同样存在差异,需要单独处理
## 滚动动态渲染 Tree

View File

@ -99,7 +99,7 @@ const parseSubAttr = (
value,
indentation: parentIndentation + 1,
};
if (hIndex) {
if (hIndex !== undefined) {
item.hIndex = hIndex;
}
result.push(item);
@ -123,14 +123,19 @@ export function parseHooks(hooks: Hook<any, any>[]) {
const result: IAttr[] = [];
const indentation = 0;
hooks.forEach(hook => {
const { hIndex, state ,type } = hook;
if (type === 'useState') {
const { hIndex, state } = hook;
// 不同 hook 的 state 有不同属性,根据是否存在该属性判断 hook 类型
// 采用这种方式是因为要拿到需要的属性值,和后续触发更新,必然要感知 hook 的属性值
// 既然已经感知了属性,就不额外添加属性进行类型判断了
if ((state as Reducer<any, any>).stateValue) {
if ((state as Reducer<any, any>).isUseState) {
parseSubAttr((state as Reducer<any, any>).stateValue, indentation, 'state', result, hIndex);
} else if (type === 'useRef') {
parseSubAttr((state as Ref<any>).current, indentation, 'ref', result, hIndex);
} else if (type === 'useReducer') {
} else {
parseSubAttr((state as Reducer<any, any>).stateValue, indentation, 'reducer', result, hIndex);
}
} else if ((state as Ref<any>).current) {
parseSubAttr((state as Ref<any>).current, indentation, 'ref', result, hIndex);
}
});
return result;
}
@ -179,9 +184,9 @@ export function buildAttrModifyData(parsedAttrsType: string, attrs: IAttr[], val
type = ModifyProps;
} else if (parsedAttrsType === 'parsedState') {
type = ModifyState;
path[0] = item.hIndex;
} else if (parsedAttrsType === 'parsedHooks') {
type = ModifyHooks;
path[0] = item.hIndex;
} else {
return null;
}