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

Previously on & Background

We discussed in detail the createASTElement method, which creates the AST, and the preTransfromNode method represented by the preTransforms variable from options.modules.

  1. createASTElementMethod to createtype1Of the elementsASTNode object containingparent,childrenAnd other attributes used to organize the relationship between nodes;
  2. preTransformsNodeThe method is to preprocess the stripv-modelAnd it’s dynamically boundtypeProperties of theinputTags are designed to solve whatevertypeBinding any value that ends up being rendered except one that meets expectationsinputElements.

The preTransformsNode () method is a preTransformsNode () method, and the preTransformsNode () method is a preTransformsNode. I thought I could fill the hole quickly, but it turned out to be bigger and bigger. Today I continue to fill the hole, and write the specific logic of the tool method options.start

ProcessPre method

Methods location: SRC/compiler/parser/index. The js – > function processPre

Method argument: Element, AST node object

The ast () method returns the value of the V-pre attribute from element’s property object. If the value is not null, the ast contains a v-pre directive. Set the value to true.

function processPre (el) {
  if (getAndRemoveAttr(el, 'v-pre') != null) {
    el.pre = true}}Copy the code

Third, getAndRemoveAttr

Method location: SRC /compiler/helpers.js

Method parameters:

  1. el:ASTThe node object
  2. name: do you want fromelThe name of the property obtained from
  3. removeFromMapWhether frommapRemove the

Methods: If name is present in el.attrsmap and the value is not null, obtain the value of the name, that is, el.attrsmap [name], and remove the item from the el.attrslist array. If removeFromMap is true, remove name from el.attrsmap.

Note that normally removeFromMap is not true and will only be removed from the el.attrslist array. This is done to prevent processAttrs because attrsMap is needed when the AST generates code.

export function getAndRemoveAttr ( el: ASTElement, name: string, removeFromMap? : boolean ): ? String {let val // remove attribute name from el.attrslist if ((val = el.attrsmap [name])! = null) { const list = el.attrsList for (let i = 0, l = list.length; i < l; I ++) {if (list[I].name === name) {list.splice(I, 1); Name if (removeFromMap) {delete el.attrsmap [name]} return val}Copy the code

Four, platformIsPreTag

Method location: This method is passed in with baseOptions when createCompiler(baseOptions), BaseOptions isPreTag methods from SRC/platforms/web/util/element js – > function isPreTag

Method parameters: tag, tag name

Function: Check whether the tag is pre, that is, check whether the current tag is


tag

export const isPreTag = (tag: ? string): boolean => tag === 'pre'Copy the code

Fifth, processRawAttrs

Methods location: SRC/compiler/parser/index. The js – > functions provides processRawAttrs

Method parameters: EL, AST node object

The attrsList () method copies the el.attrs array to the el.attrs array. Why do you do that?

This is because when inVPre is true, the v-Pre directive is used on the current node, and the v-Pre directive is used to make the current node and its children static nodes. {{}} syntax is not processed even on nodes using V-Pre.

Each entry in the el.attrs array is of the form {name: attrName, value: attrVal, start, end}. In addition, attributes on el.attrs are static attributes and are ignored when data is updated.

  • processRawAttrsCall your
// Indicate where the processRawAttrs method is called, leaving out many of the details of the original parse and parseHTML methods
export functions parse () {
  parseHTML(template, {
    // options.start
    start () {
       / /... omit
       if (inVPre) 
         // If inVPre is true, the current node has a V-pre directive
         ProcessRawAttrs example method call
         processRawAttrs(element)
        }
    }
  })
}
Copy the code
  • processRawAttrsmethods
function processRawAttrs (el) {
  const list = el.attrsList // The original attrsList attribute
  const len = list.length
  if (len) {
    const attrs: Array<ASTAttr> = el.attrs = new Array(len)
    for (let i = 0; i < len; i++) {
      attrs[i] = {
        name: list[i].name,
        value: JSON.stringify(list[i].value)
      }
      if(list[i].start ! =null) {
        attrs[i].start = list[i].start
        attrs[i].end = list[i].end
      }
    }
  } else if(! el.pre) {// non root node in pre blocks with no attributes
    el.plain = true}}Copy the code

Six, processFor

Methods location: SRC/compiler/parser/index. The js – > functions provides processFor

Method argument: Element, AST node object

The v-for () method processes the v-for instruction on a node and saves the result of parsing to an element. {for: iterable object, alias: iterable item name}

Take the following code for example:

<span v-for="item in someArr" :key="index">{{item}}</span>

<! -- someArr = ['A', 'B', 'C', 'D'] -->
Copy the code

The iterable is someArr, and the name of the iterable item is item;

export function processFor (el: ASTElement) {
  let exp
  // Get the value of the v-for attribute on el. V-for is an instruction, but is an inline attribute in ast
  if ((exp = getAndRemoveAttr(el, 'v-for'))) {
    // item in someArr,
    // get {for: iterable, alias: alias}
    const res = parseFor(exp)
    if (res) {
      // Copy properties from res to el,
      // el.for = "someArr"
      // el.alias = "item" 
      extend(el, res)
    } else if(process.env.NODE_ENV ! = ='production') {
      warn(
        `Invalid v-for expression: ${exp}`,
        el.rawAttrsMap['v-for'])}}}Copy the code

6.1 parseFor

Methods location: SRC/compiler/parser/index. Js – > parseFor

Method parameter: expression corresponding to v-for instruction on ast object, such as “item in someArr”;

Function of the method: the expression of the V-for instruction item in someArr is parsed out with various regulars, and the iterable someArr and the iterable item are obtained.

export function parseFor (exp: string): ?ForParseResult {
  // exp = v-for="item in someArr
  
  // inMatch: ["item in someArr", "item", "someArr"]
  const inMatch = exp.match(forAliasRE)
  if(! inMatch)return
  const res = {}
  res.for = inMatch[2].trim()
  const alias = inMatch[1].trim().replace(stripParensRE, ' ')
  const iteratorMatch = alias.match(forIteratorRE)
  if (iteratorMatch) {
    res.alias = alias.replace(forIteratorRE, ' ').trim()
    res.iterator1 = iteratorMatch[1].trim()
    if (iteratorMatch[2]) {
      res.iterator2 = iteratorMatch[2].trim()
    }
  } else {
    res.alias = alias
  }
  return res
}
Copy the code

Here’s what parseFor(exp) looks like:

Seven,

This article continues with the previous discussion of the options.start utility methods:

  1. ProcessPre: Checks whether there is a v-pre directive on the element, if there is, set el. Pre to true;

  2. GetAndRemoveAttr: Get the value of the specified attribute name from el.attrsMap and remove the attribute from the el.attrsList array. If removeFromMap is passed, remove the attribute from attrsMap.

  3. PlatformIsPreTag: Checks whether it is a pre tag.

  4. ProcessRawAttr: Copies the attributes on the element into the el.attrs array, which has static attributes and ignores them when the data changes

  5. ProcessFor: processes the V-for instruction, resulting in {for: iterable, alias: iterable entry name}