“This is the 24th day of my participation in the First Challenge 2022. For details: First Challenge 2022.”

Previously on & Background

The closeElement tool methods are discussed as follows:

  1. ProcessSlotOutlet: Resolves the slot labels of the closed and gets the slot name set to the EL;

  2. ProcessComponent: Resolves dynamic components, resolves IS properties and inline-template

  3. Transforms: transoformNode methods exported by the class/style module process static and dynamic class names or styles

  4. ProcessAttrs: Handles attrs on elements, parameters of instructions, event bindings, modifiers, and so on;

This is the end of closeElment, and all the logic of options.start has been completed. In this installment we will complete the options last callback method: options.end. The options.end method is used to handle the closing tag of non-closed and tag.

In addition to the options.end method, we’ll review the overall flow of the parse and parseHTML methods. Also, as can be seen from the title, we are discussing the mount logic of Vue, which makes parse long, as long as a northern winter, 😘😘

Second, the options. The end

Method location: callback method of parseHTML options

Method parameters:

  1. Tag: indicates the name of the tag
  2. Start: indicates the start index position
  3. End: indicates the end index position

The method handles the end tag as follows:

  1. To obtainstackThe stack elementselementAnd make it out of the stack;
  2. maintenancecurrentParent, after the previous step out of the stack,stackThe element at the top of the stack iselement çš„ parent;
  3. callcloseElementTo complete processing of the label, callprocessElementHandling node attributes, and then organizing parent-child relationships between nodes is done in this way, and we talked about this way in the previous chapter when we talked about autism and tags, so I won’t go over it here
export function parse (template: string, options: CompilerOptions) :ASTElement | void {
  
  parseHTML(template, {
    start (tag, attrs, unary, start, end) {
    },

    end (tag, start, end) {
     const element = stack[stack.length - 1]
      // pop stack
      stack.length -= 1

      // Get currentParent parent, not sibling,
      // Because each time a node is processed, it will exit the stack.
      // Even if there is a younger node, by the time the younger node is processed, the older node is already out of the stack
      currentParent = stack[stack.length - 1]
      if(process.env.NODE_ENV ! = ='production' && options.outputSourceRange) {
        element.end = end
      }

      closeElement(element)
    }
  })
Copy the code

Thinking about? So this is a little bit tricky, and I’m going to take a little bit of space to talk about it, but here’s a question for you to think about, in options.start we’re going to set the current currentParent to the start tag when we detect a non-autistic tag, But when you go to the close tag you want to set currentParent to the element at the top of the stack why is that?

We’ll examine the currentParent update process with this simple template code:

<div id="outer">
  <span id="prev">someTxt</span>
  <i id="next">someItalyTxt</i>
</div>
Copy the code
  1. When parsing to

  2. The parent of span#prev is div#inner. Create an ast for span#prev, update currentParent to span#prev, and push stack=[div#outer, span#prev]; Currentparent.children (span#inner. Children);

  3. Continue parsing to , which is a closed tag, and call options.end. Get the top element of the stack and assign it to element, element = span#prev, and then stack=[div#outer]; 😂😂😂 : select * from div#outer where currentParent = stack;

  4. Then it’s time to explain why it makes sense. CurrentParent = div#outer; div#outer = div#outer; When executing start and end logic, currentParent will always be a correct value.

In short, currentParent is maintained in start to identify the parent element of any start tag encountered after the current start tag as the current element, such as span#prev encountered after div#outer. The parent element of span#prev is div#outer;

The parent element is the parent element of the current element when a start tag is encountered after the end tag. For example, the end tag of span#prev is followed by the start tag of i#next;

Review the parse method

One of the mounting steps in Vue is to compile the HTML template into an AST node object tree, and the Parse method is the way to do this.

3.1 Parse is invoked

Parse is called in the baseCompile passed in when createCompilerCreator(baseCompile) is called to generate createCompiler:

export const createCompiler = createCompilerCreator(function baseCompile (template: string, options: CompilerOptions) :CompiledResult {
  / / the parse calls
  const ast = parse(template.trim(), options)
})
Copy the code

3.2 the parse method

The parse method uses parseHTML to parseHTML templates into AST, reorganize parent-child relationships between nodes through stack and currentParent, and finally form a tree. Finally, the AST object root of the top-level node is returned.

export function parse () {
  //....
  parseHTML(template, {
    start () {},
    end () {},
    chars () {}
    comment () {}
  })
  return root
}
Copy the code

3.3 parseHTML method

The implementation of the parseHTML method, which is actually used to parseHTML template strings, is a highlight:

While (HTML), using < as the identifier by looking for the index position where the < < sign appears, and parsing the content after < into different types: comment, conditional comment, document declaration, copy, opening tag, closing tag, and then calling the callback method it receives: Options.com ment, options.chars, options.star, options.end Handle the corresponding types;

Whatever type is hit, then update the index according to the length of the content of the processing type, then re-intercept the HTML template with index and copy it to THE HTML, so that the HTML with index as a pointer is gradually shortened, and finally the whole HTML is processed;

This approach is not designed to be recursive, but to be handled in a simple way, which improves efficiency and reduces memory footprint. In simple terms, a one-dimensional while loop traverses a deep tree structure, which is worth learning from.

3.3.1 options. The start

Options. start is used to process the start tag parseHTML parses.

  1. createastNode object, the first one that gets resolved to the start tag isparseMethod to returnrootNode;
  2. callpreTransformNodeDealing withv-modelThe directiveinputTag, intended to handle dynamic bindingtypeAnd solve dynamic binding with brute forcetype çš„ inputThe rendering problem of the tag, i.e: type or v - bind: type;
  3. maintenancestack 和 currentParent, so that the parent element of the start tag parsed thereafter is the current element;
  4. If the current label is closed and label, it is not pushed directlystack, directly callcloseElementParse the element;

3.3.2 rainfall distribution on 10-12 options. The end

The options.end method is used to process the end tag parseHTML parses to.

  1. maintenanceStack, currentParentMake all need to organize the parent-child relationship to ensure the correctness of the father node;
  2. callcloseElementComplete the processing of non-autistic and tags: node attributes organize parent-child relationship;

3.3.3 options. Chars

Generate a text node and insert it into currentParent.children

3.3.4 options.com ment

Generate a comment node and insert it into current-.childrend

Four,

  1. This short composition is finishedparseHTMLThe last callback method ofoptions.endThe discussion;
  2. itcurerntParent 在 start 和 endThe updating function of the
  3. Review the entireparsemethodsparseHTMLThe synopsis method and its function;