An overview of the

The patch function is executed after the dependency is triggered. What does it do?

Patch is used to update the DOM by comparing the old and new virtual DOM. There are so many knowledge points involved that we must analyze them step by step.

The use of h functions

const h = (type, props, children) = > {
    return createVNode(type, props, children);
};
/ / use
h("div", {cc: 1132}, [
     h("p", {aaa: 111}, "apiInject"), 
     h(ProviderOne, {aaa: 222})]); h(ProviderTwo);// ProviderTwo is a component
Copy the code

Analyze the three parameters of createVNode by using h function:

Type: 1, HTML tag; 2. A component.

Props: Is an attribute. 1. If type is a tag, props is an attribute of the tag. 2. If type is a component, props can be received in its setup; 3, no is undefined.

Children: 1. String: text child element content; 2, array: multiple child elements, you can use h function inside.

CreateVNode: Parameter of the h function => VNode

const createVNode = function (type, props, children) {
    const vnode = {
        el: null.component: null.key: props === null || props === void 0 ? void 0 : props.key,
        type,
        props: props || {},
        children,
        shapeFlag: getShapeFlag(type),
    };
    if (Array.isArray(children)) {
        vnode.shapeFlag |= 16;
    }
    else if (typeof children === "string") {
        vnode.shapeFlag |= 8;
    }
    normalizeChildren(vnode, children);
    return vnode;
};
Copy the code

Three parameters produce vNodes

const vnode = {
    el: null.component: null.key: props === null || props === void 0 ? void 0 : props.key,
    type,
    props: props || {},
    children,
    shapeFlag: getShapeFlag(type),
};
Copy the code

To generate the key

Key: Props is used if there is a key. If there is no key, this parameter is set to 0.

Generate shapeFlag

ShapeFlag: Sets a flag: string: 1; Array: 4

function getShapeFlag(type) {
    return typeof type === "string"
        ? 1
        : 4;
}
Copy the code

Four markers are generated

  1. The value of type is string (label) and children is array: shapeFlag = 17
  2. Type is string (label, children is string: shapeFlag = 9
  3. Type: component; children: array: shapeFlag = 20
  4. Type is component, children is string: shapeFlag = 12
if (Array.isArray(children)) {
    vnode.shapeFlag |= 16;
} else if (typeof children === "string") {
    vnode.shapeFlag |= 8;
}
Copy the code

Perform normalizeChildren

Typeof children === “object” shapeFlag is 17 and 20, respectively

  1. 17 times 1 is 1
  2. 20 & 1 = 0 implement vnode. ShapeFlag | = 32: shapeFlag = 52
function normalizeChildren(vnode, children) {
    if (typeof children === "object") {
        if (vnode.shapeFlag & 1);else {
            vnode.shapeFlag |= 32; }}}Copy the code

The final result

type\children string array undefined
The label string 9 17 1
The component object 12 52 4

Call patch for the first time

const render = (vnode, container) = > {
    patch(null, vnode, container);
};
Copy the code

Patch source

function patch(n1, n2, container = null, parentComponent = null) {
        const { type, shapeFlag } = n2;
        switch (type) {
            case Text:
                processText(n1, n2, container);
                break;
            case Fragment:
                processFragment(n1, n2, container);
                break;
            default:
                if (shapeFlag & 1) {
                    // console.log(" Handle element");
                    processElement(n1, n2, container);
                }
                else if (shapeFlag & 4) {
                    // console.log(" handle Component ");processComponent(n1, n2, container, parentComponent); }}}Copy the code

Type: specifies the name of the component object or tag, excluding Text and Fragment

Combined with the above table, it can be concluded that:

  1. 17, 1, 9 (type is label) execute processElement(n1, n2, container)
  2. ProcessComponent (n1, n2, container, parentComponent);

It’s too long. Deal with tags and components and write a separate article