This is the sixth day of my participation in the August Text Challenge.More challenges in August

Introduction to Template Compilation

  • The main purpose of template compilation is to convert a template to render.
<div>
    <h1 @click="handler">title</h1>
    <p>some content</p>
</div>
Copy the code
  • Render function – Review
render (h) {
    return h('div', [
        h('h1', { on: { click: this.handler } }, 'title'),
        h('p'.'some content')])}Copy the code

The role of template compilation

  • Use Vue2. XVNodeDescribes the view and various interactions, written by the userVNodeMore complicated
  • Users just need to write similarHTMLThe code –Vue.jsTemplate, which is converted to return by the compilerVNoderenderfunction
  • .vueThe file will bewebpackDuring the build processrenderfunction

Template compilation – example

<body>
    <div id="app">
        <h1>Vue <span>Template compilation process</span></h1>
        <p>{{ msg }}</p>
        <comp  @myclick="handler"></comp>
    </div>
</body>
<script>
Vue.component('comp', {
    template: '<div>I am a comp</div>'
})
const vm = new Vue({
    el: '#app'.data: {
        msg: 'Hello compiler'
    },
    methods: {
        handler() {
            console.log('test')}}})console.log(vm.$options.render)

</script>
Copy the code

The result of compiling the template

(function anonymous() {
  with(this) {
    return _c(
      "div",
      { attrs: { id: "app" } },
      [
        _m(0),
        _v(""),
        _c("p", [_v(_s(msg))]),
        _v(""),
        _c("comp", { on: { myclick: handler } }),
      ],
      1); }})Copy the code

Vue Template Explorer

  • Vue2 template to render function
  • Vue3 template to render function

compile

  • compileToFunctions(template, {}, this)
  • createCompiler(baseOptions)
  • createCompilerCreator(function baseCompile(){})

compileToFunctions

export function createCompilerCreator (baseCompile: Function) :Function {
  // baseOptions Platform-related options
  // SRC \platforms\web\compiler\options.js
  return function createCompiler (baseOptions: CompilerOptions) {
    function compile() {
      // ...
      // ...
    }

    return {
      compile,
      compileToFunctions: createCompileToFunctionFn(compile)
    }
  }
}
Copy the code

compile

Core: Merge options, call baseCompile for compilation

function compile (template: string, options? : CompilerOptions) :CompiledResult {}Copy the code

baseCompile – AST

// `createCompilerCreator` allows creating compilers that use alternative
// parser/optimizer/codegen, e.g the SSR optimizing compiler.
// Here we just export a default compiler using the default parts.
export const createCompiler = createCompilerCreator(function baseCompile (template: string, options: CompilerOptions) :CompiledResult {
  // Convert the template to an AST abstract syntax tree
  // Abstract syntax tree, used to describe code structure in a tree manner
  const ast = parse(template.trim(), options)
  if(options.optimize ! = =false) {
    // Optimize the abstract syntax tree
    optimize(ast, options)
  }
  // Generate the abstract syntax tree as a string of JS code
  const code = generate(ast, options)
  return {
    ast,
    // Render function
    render: code.render,
    // Static rendering function to generate a static VNode tree
    staticRenderFns: code.staticRenderFns
  }
})

Copy the code

Note here:

What is an abstract syntax tree

  • Abstract syntax tree abbreviationAST(Abstract Syntax Tree)
  • Describe the code structure of a tree in the form of an object
  • The abstract syntax tree here is used to describe the tree structureHTMLstring

Why use abstract syntax trees

  • Template string converted toASTAfter, can passASTOptimize the template
  • Tag the static content in the template inpatchSkip the static content
  • inpatchThe process of static content does not require comparison and re-rendering

baseCompile – parse

// Convert the template to an AST abstract syntax tree
// Abstract syntax tree, used to describe code structure in a tree manner
const ast = parse(template.trim(), options)


parseHTML(template, {
    warn,
    expectHTML: options.expectHTML,
    isUnaryTag: options.isUnaryTag,
    canBeLeftOpenTag: options.canBeLeftOpenTag,
    shouldDecodeNewlines: options.shouldDecodeNewlines,
    shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref,
    shouldKeepComment: options.comments,
    outputSourceRange: options.outputSourceRange,
    start, 
    end,
    chars,
    comment)
}
Copy the code

baseCompile – optimize

// Optimizing the abstract syntax tree is to mark static nodes etc
// src/compiler/optimizer.js 
function optimize(root: ? ASTElement, options: CompilerOptions);
Copy the code

generate

// Generate the abstract syntax tree as a string of JS code
  const code = generate(ast, options)
  
  export function generate(
    ast: ASTElement | void,
    options: CompilerOptions
  ) :CodegenResult {
    / /...
    const code = ast ? genElement(ast, state) : '_c("div")'
  }
  
  export function genElement (el: ASTElement, state: CodegenState) :string {
      / /...
      / /...
      // Handle static
      if(el.staticRoot && ! el.staticProcessed) {return genStatic(el, state)
      }
  }
Copy the code

Template compilation process


Componentization review

  • aVueA component is one that has predefined optionsVueThe instance
  • A component can form a fully functional area on a page, and a component can contain scripts, styles, and templates

The component registration

  • Global components
cosnt Comp = Vue.component('comp', {
    template: '<div>Hello Component</div>'
})
const vm = new Vue({
  el: '#app'.render(h) {
      return h(comp)
  }
})
Copy the code
  • Local components

  • Vue.extend

Review the first rendering process

  • VueThe constructor
  • this._init()
  • this.$mount()
  • mountComponent()
  • new Watcher()Apply colours to a drawingWatcher
  • updateComponent()
  • vm._render() -> createElement()
  • vm._uodate()