preface

First of all, this article has absolutely nothing to do with our daily development and coding, and it’s all about spending so much time trying to find solace in the fact that we’re mentally incompetent.

CloneIfMounted and normalizeVNode often appear when I read diff source code. I looked up the information at that time, I probably wrote only initialization vNode at night, but when I studied patch, the brothers appeared again. Then hand cheap point in the look, found a cloneVNode, suddenly have some doubts, this cloneVNode is what to do.

Waste of time

When it comes to clone, I immediately think of render, after all, it must be something that exists to clone. And then find the h function.

function h(type, propsOrChildren, children) {
    const l = arguments.length;
    if (l === 2) {
        if(shared.isObject(propsOrChildren) && ! shared.isArray(propsOrChildren)) {// single vnode without props
            if (isVNode(propsOrChildren)) {
                return createVNode(type, null, [propsOrChildren]);
            }
            // props without children
            return createVNode(type, propsOrChildren);
        }
        else {
            // omit props
            return createVNode(type, null, propsOrChildren); }}else {
        if (l > 3) {
            children = Array.prototype.slice.call(arguments.2);
        }
        else if (l === 3 && isVNode(children)) {
            children = [children];
        }
        returncreateVNode(type, propsOrChildren, children); }}Copy the code

It turns out it has nothing to do with clone. There is no choice but to console the source code to see what vNodes need to be cloned.

<template>
  <div>
    <div>i am a static div</div>
    <div>i am a static div {{number}}</div>
    <button @click="handleChangeNum">{{number}} Modify button</button>
  </div>
</template>
Copy the code

I wrote the simplest example where the number starts at 111 and I hit +1.

At first, there was no log message, and after I clicked the button, I saw the light.

In fact, when this log comes out, I can almost confirm that it has something to do with static DOM optimization in VUe3.

Looking back, the normalizeVNode function also printed information.

It can be seen that children have 3, but dynamicChilren only has 2, the less one is the clone plain text div.

Puzzle solved, but you think this is the end of it?

No, because in the previous h function, we found that the createVNode was re-created, and we did not see Clone. How is the h function optimized?

Continue to waste time

I went ahead and wrote a child component, HelloWorld, to verify my guess.

export default {
  name: 'HelloWorld'.props: ['number'].render() {
    return h(
        'div',
        {
          class: 'home'},this.number + '222222',
          h('div'.'lalalala')])}}Copy the code

The parent component introduces HelloWorld, the parent component clicks the button to update the number, and the child component’s render is triggered.

First, dynamicChildren become null, and then lalalala is not clone.

<template>
  <div class="home">
    {{number + '2222'}}
    <div>
      lalalahahaha
    </div>
  </div>
</template>
Copy the code

Set render to template and continue to render.

DynamicChildren reappeared and lalalahahaha was clone Ed in the update.

And continue to waste time

I should have stopped at this point, but as soon as I realized that I’m here, I might as well continue.

See how the HTML we write with template will be parsed.

Hosted_1 is the parent div of helloWorld, and hoisted_2 is the fixed text lalalahahaha, which is 1112222. CreateBlock these unmasked functions.

Let’s see if we can use our ownrenderThe printing of the function is not very similar, it is exactly the same.

conclusion

That’s the end of this article.

It is not really over, but I want to end it, because I saw patchBlockChildren and patchChildren again. To put it simply, I just need to look at it by myself, and the words I write are not very interesting, which will make the already boring words worse.

I’ve figured out what cloneVNode is for, but it doesn’t feel that way.

Instead of using render, we can just write template, ok?