Match-id-24869a4d9d0e8b1c76ab1cc13b9f59438677e5f5

This commit is contained in:
* 2022-03-23 19:24:12 +08:00 committed by *
commit fce8dca047
11 changed files with 66 additions and 39 deletions

View File

@ -1,2 +1,3 @@
**/node_modules
build/
*.d.ts

View File

@ -1,6 +1,8 @@
module.exports = {
extends: [
'eslint:recommended',
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
'prettier',
],
root: true,
@ -41,6 +43,9 @@ module.exports = {
'no-for-of-loops/no-for-of-loops': 'error',
'no-function-declare-after-return/no-function-declare-after-return': 'error',
},
globals: {
isDev: true
},
overrides: [
{
files: [

View File

@ -1 +1,4 @@
declare var isDev: any;
/*
*/
declare var isDev: boolean;

View File

@ -35,6 +35,7 @@ import {
updateParentsChildShouldUpdate,
updateShouldUpdateOfTree
} from './vnode/VNodeShouldUpdate';
import { getPathArr } from './utils/vNodePath';
// 不可恢复错误
let unrecoverableErrorDuringBuild: any = null;
@ -142,11 +143,11 @@ function handleError(root, error): void {
}
// 判断数组中节点的path的idx元素是否都相等
function isEqualByIndex(idx: number, nodes: Array<VNode>) {
let val = nodes[0].path[idx];
for (let i = 1; i < nodes.length; i++) {
let node = nodes[i];
if (val !== node.path[idx]) {
function isEqualByIndex(idx: number, pathArrays: string[][]) {
const first = pathArrays[0][idx];
for (let i = 1; i < pathArrays.length; i++) {
const pathArr = pathArrays[i];
if (idx >= pathArr.length || first !== pathArr[idx]) {
return false;
}
}
@ -179,29 +180,19 @@ export function calcStartUpdateVNode(treeRoot: VNode) {
return treeRoot;
}
// 找到路径最短的长度
let minPath = toUpdateNodes[0].path.length;
for (let i = 1; i < toUpdateNodes.length; i++) {
let pathLen = toUpdateNodes[i].path.length;
if (pathLen < minPath) {
minPath = pathLen;
}
}
const pathArrays = toUpdateNodes.map(node => getPathArr(node));
// 找出开始不相等的idx
let idx = 0;
for (; idx < minPath; idx++) {
if (!isEqualByIndex(idx, toUpdateNodes)) {
break;
}
let commonPathEndIndex = 0;
while (isEqualByIndex(commonPathEndIndex, pathArrays)) {
commonPathEndIndex++;
}
// 得到相等的路径
const startNodePath = toUpdateNodes[0].path.slice(0, idx);
const startNodePath = pathArrays[0].slice(0, commonPathEndIndex);
let node = treeRoot;
for (let i = 1; i < startNodePath.length; i++) {
const pathIndex = Number(startNodePath[i]);
node = getChildByIndex(node, pathIndex);
node = getChildByIndex(node, pathIndex)!;
}
return node;

View File

@ -6,17 +6,24 @@ class Component<P,S,C> {
context: C;
state: S | null;
refs: any;
setState: any;
forceUpdate: any;
isReactComponent: boolean;
constructor(props: P, context: C) {
this.props = props;
this.context = context;
}
setState(state: S) {
if (isDev) {
console.error('Cant not call `this.setState` in the constructor of class component, it will do nothing');
}
}
}
// 兼容三方件 react-lifecycles-compat它会读取 isReactComponent 属性值,不添加会导致 eview-ui 官网白屏
Component.prototype.isReactComponent = true;
/**
* PureComponent
*/

View File

@ -17,6 +17,7 @@ import {
isObjectType,
} from './DiffTools';
import { travelChildren } from '../vnode/VNodeUtils';
import { markVNodePath } from '../utils/vNodePath';
enum DiffCategory {
TEXT_NODE = 'TEXT_NODE',
@ -241,7 +242,7 @@ function diffArrayNodesHandler(
prevNewNode.next = newNode;
newNode.cIndex = prevNewNode.cIndex + 1;
}
newNode.path = newNode.parent.path + newNode.cIndex;
markVNodePath(newNode);
prevNewNode = newNode;
}
@ -477,7 +478,7 @@ function setVNodesCIndex(startChild: VNode | null, startIdx: number) {
while (node !== null) {
node.cIndex = idx;
node.path = node.parent.path + node.cIndex;
markVNodePath(node);
node = node.next;
idx++;
}
@ -528,7 +529,7 @@ function diffStringNodeHandler(
}
newTextNode.parent = parentNode;
newTextNode.cIndex = 0;
newTextNode.path = newTextNode.parent.path + newTextNode.cIndex;
markVNodePath(newTextNode);
return newTextNode;
}
@ -606,7 +607,8 @@ function diffObjectNodeHandler(
resultNode.parent = parentNode;
resultNode.cIndex = 0;
resultNode.path = resultNode.parent.path + resultNode.cIndex;
markVNodePath(resultNode);
if (startDelVNode) {
deleteVNodes(parentNode, startDelVNode);
}

View File

@ -8,6 +8,7 @@ import {
TYPE_PROFILER,
TYPE_STRICT_MODE,
} from '../../external/JSXElementType';
import { markVNodePath } from '../utils/vNodePath';
export function bubbleRender() {}
@ -20,7 +21,7 @@ export function captureMemoComponent(
const newProps = mergeDefaultProps(Component, processing.props);
if (processing.isCreated) {
let newChild = null;
let newChild: VNode | null = null;
const type = Component.type;
if (type === TYPE_STRICT_MODE || type === TYPE_FRAGMENT || type === TYPE_PROFILER) {
newChild = createFragmentVNode(null, newProps.children);
@ -29,7 +30,7 @@ export function captureMemoComponent(
}
newChild.parent = processing;
newChild.ref = processing.ref;
newChild.path = newChild.parent.path + newChild.cIndex;
markVNodePath(newChild);
processing.child = newChild;
return newChild;
@ -48,7 +49,7 @@ export function captureMemoComponent(
const newChild = updateVNode(firstChild, newProps);
newChild.parent = processing;
newChild.cIndex = 0;
newChild.path = newChild.parent.path + newChild.cIndex;
markVNodePath(newChild);
newChild.ref = processing.ref;
processing.child = newChild;

View File

@ -11,6 +11,7 @@ import {pushForceUpdate} from '../UpdateHandler';
import {launchUpdateFromVNode, tryRenderFromRoot} from '../TreeBuilder';
import {updateShouldUpdateOfTree} from '../vnode/VNodeShouldUpdate';
import {getContextChangeCtx} from '../ContextSaver';
import { markVNodePath } from '../utils/vNodePath';
export enum SuspenseChildStatus {
Init = '',
@ -44,7 +45,7 @@ function createFallback(processing: VNode, fallbackChildren) {
fallbackFragment.parent = processing;
fallbackFragment.eIndex = 1;
fallbackFragment.cIndex = 1;
fallbackFragment.path = fallbackFragment.parent.path + fallbackFragment.cIndex;
markVNodePath(fallbackFragment);
processing.suspenseChildStatus = SuspenseChildStatus.ShowFallback;
return fallbackFragment;
@ -76,7 +77,7 @@ function createSuspenseChildren(processing: VNode, newChildren) {
childFragment.parent = processing;
childFragment.cIndex = 0;
childFragment.path = childFragment.parent.path + childFragment.cIndex;
markVNodePath(childFragment);
processing.child = childFragment;
processing.promiseResolve = false;
return processing.child;

View File

@ -0,0 +1,15 @@
import { VNode } from '../vnode/VNode';
const PATH_DELIMITER = ',';
/**
* VNode在VNode树中的路径
* @param vNode
*/
export function markVNodePath(vNode: VNode) {
vNode.path = `${vNode.parent!.path}${PATH_DELIMITER}${vNode.cIndex}`;
}
export function getPathArr(vNode: VNode) {
return vNode.path.split(PATH_DELIMITER);
}

View File

@ -26,6 +26,7 @@ import {
} from '../../external/JSXElementType';
import { VNode } from './VNode';
import { JSXElement } from '../Types';
import { markVNodePath } from '../utils/vNodePath';
const typeLazyMap = {
[TYPE_FORWARD_REF]: ForwardRef,
@ -135,7 +136,7 @@ export function createUndeterminedVNode(type, key, props) {
export function createTreeRootVNode(container) {
const vNode = newVirtualNode(TreeRoot, null, null, container);
vNode.path += 0;
vNode.path = '0';
vNode.updates = [];
return vNode;
}
@ -147,7 +148,7 @@ export function createVNode(tag: VNodeTag | string, ...secondArg) {
case TreeRoot:
// 创建treeRoot
vNode = newVirtualNode(TreeRoot, null, null, secondArg[0]);
vNode.path += 0;
vNode.path = '0';
vNode.updates = [];
break;
@ -178,7 +179,7 @@ export function onlyUpdateChildVNodes(processing: VNode): VNode | null {
let child: VNode | null = processing.child;
while (child !== null) {
updateVNode(child, child.props);
child.path = child.parent.path + child.cIndex;
markVNodePath(child);
child = child.next;
}
}
@ -209,7 +210,7 @@ export function onlyUpdateChildVNodes(processing: VNode): VNode | null {
while (queue.length) {
const vNode = queue.shift()!;
vNode.path = vNode.parent.path + vNode.cIndex;
markVNodePath(vNode);
putChildrenIntoQueue(vNode)
}

View File

@ -34,8 +34,8 @@
},
"include": [
"./libs/**/src/**/*.ts",
"libs/index.d.ts"
"libs/horizon/index.d.ts"
],
"exclude": ["node_modules", "**/*.spec.ts", "dev"],
"types": ["node"],
"types": ["node"]
}