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

34. Talk about Vue templates and render functions

What is a Vue template?

Template is an HTML-like syntax provided by Vue that is used to write page structures. You can write HTML, instructions, interpolation and JS expressions on the template. The syntax is easy to understand and write, but it is not flexible enough.

What is the render function?

The render function is another way for Vue to write a page. In addition to template, Vue can write a page with the render function in combination with createElement or JSX. The Render function is closer to the compiler than template.

What is createElement?

CreateElement is a function provided by Vue that generates a VNode by passing in tag, data, and children.

CreateElement is defined in the Vue source code as follows:

$createElement: (tag? : string | Component, data? : Object, children? : VNodeChildren) => VNode;Copy the code

What is JSX?

JSX is a JavaScript syntactic extension that nicely describes how the UI should behave the way it should interact, with all the functionality and flexibility of JavaScript. – the react document

In Vue development, using the Render function + JSX is much easier to write than using the Render function + createElement.

Let’s use a diagram to summarize common component writing:

Most of the day to day development uses the Template component, but in some special cases it is more convenient to use the Render function + JSX.

The differences between the three components

As an example, suppose we want to implement a header component that uses one of the h1-H6 tags based on the level value passed in.

We implement this component in each of the three ways described above:

template

<custom-title :level="1">hello world</custom-title>
Copy the code
CustomTitle components inside the < div > < h1 v - if = "level = = = 1" > < slot > < / slot > < / h1 > < h2 v - if = "level = = = 2" > < slot > < / slot > < / h2 > < h3 v-if="level === 3"> <slot></slot> </h3> <h4 v-if="level === 4"> <slot></slot> </h4> <h5 v-if="level === 5"> <slot></slot> </h5> <h6 v-if="level === 6"> <slot></slot> </h6> </div> props: { level: { type: Number, default: 1 } }Copy the code

With template, the code is verbose and has a lot of repetitive logic.

Render function + createElement

props: {
  level: {
    type: Number,
    default: 1
  }
},
render(createElement) {
  return createElement('h' + this.level, this.$slots.default)
}
Copy the code

Using the Render function + createElement is much simpler, but the code is not easy to understand and you need to understand the createElement method.

Render function + JSX

props: {
  level: {
    type: Number,
    default: 1
  }
},
render() {
  const Tag = `h${this.level}`
  return <Tag>{this.$slots.default}</Tag>
}
Copy the code

Using render function + JSX, the code is concise, and the code is easy to understand, although it is also full of JS syntax, but looks like HTML.

Here’s another example of this code:

<custom-title :level="1"> 
  <span>Hello</span> world! 
</custom-title>
Copy the code

Write with createElement:

render: function (createElement) {
  return createElement(
    'custom-title', {
      props: {
        level: 1
      }
    }, [
      createElement('span', 'Hello'),
      ' world!'
    ]
  )
}
Copy the code

Written in JSX:

render: function () {
  return (
    <CustomTitle level={1}>
      <span>Hello</span> world!
    </CustomTitle>
  )
}
Copy the code

Obviously, the experience with JSX is much better.

Note: VUE-CLI 3.0 and above automatically supports JSX, and if you build your own VUE project, you need to introduce some Babel plug-ins, such as @vue/ babel-PRESET – JSX

35. Describe the process of Vue template compilation

In the Vue documentation, there is an example of compiling a template string in real time, with the address here

A template like this:

<div>
  <p>{{ message }}</p>
</div>
Copy the code

Will compile to:

function anonymous(
) {
  with(this){return _c('div',[_c('p',[_v(_s(message))])])}
}
Copy the code

So how does that work? Let’s analyze it.

With statement

We see that the compiled JS code uses the with statement.

The with syntax is not commonly used and is not recommended, but is used in Vue template compilation, so we will learn about it.

The with statement is used to set the code scope to a specific object. The syntax is:

with (expression) {
    statement
}
Copy the code
  • It can change the rules for finding free variables in a code block as if they were attributes of an object.
  • If no matching object attribute is found, an error is reported.

Here’s an example:

Both name and age are printed out. Printing sex is an error.

Use with with with. It breaks scope rules and makes it less readable. Look at the following example:

function f(x, obj) {
  with (obj)
    print(x);
}
Copy the code

I don’t know if I’m taking the value of the function or the value of the object obj.

Off topic, check out MDN for more

We continue to analyze the use of with in Vue source code.

with(this){return _c('div',[_c('p',[_v(_s(message))])])}
Copy the code

_c, _v, _S, message, etc

this._c
this._v
this._s
this.message
Copy the code

We know that this is the vm instance, this.message is easy to understand, but what is this._c, this._v, this._s?

Function for

Read the Vue source code just know, these three things are actually the abbreviation of the function name

this._c = function (a, b, c, d) { return createElement(contextVm, a, b, c, d, needNormalization); };
Copy the code
export function installRenderHelpers (target: any) {
  ...
  target._s = toString
  ...
  target._v = createTextVNode
  ...
}
Copy the code
_c: ( vnode? : VNode, data? : VNodeData, children? : VNodeChildren, normalizationType? : number ) => VNode | void; _s: (value: mixed) => string; _v: (value: string | number) => VNode;Copy the code

_c is ·createElement, _s is toString, _v is createTextVNode.

Translation:

<div> 
  <p>{{ message }}</p> 
</div>

with(this){return _c('div',[_c('p',[_v(_s(message))])])}

with(this){
  return createElement('div', [
    createElement('p', [
      createTextVNode(toString(message))
    ])
  ])
}
Copy the code

The HTML template is converted to JS code.

The build process

What happens when a template is converted to JS? It can be summarized in the following steps

  • Parsing template strings to generate AST (Abstract Syntax Tree)
  • Optimize AST to facilitate subsequent virtual DOM updates
  • Turn AST into executable code (render function)
  • Execute the render function to generate a VNode

Vue source code looks like this:

Const baseCompile = (template, options) => {const ast = parse(template.trim(), options) Const code = generate(AST, options) const code = generate(AST, options) // Render the AST into executable code code.render, staticRenderFns: code.staticRenderFns } }Copy the code

The intermediate process is very complicated. Alin’s liver is indeed immobile. For more detailed process, please refer to these two articles:

  • Vue template compilation principle
  • Vue. Js technology reveal – compilation part

summary

The Vue template is compiled using the tempalte -> render function -> VNode to generate a virtual DOM ready for responsiveness.

If my article is helpful to you, your like 👍 is the biggest support for me ^ _ ^

The issue of

Master LRU Cache from keep-alive source code

Vue 100 Q (30-33 Q) What are the communication methods between Vue components?

Vue 100 ASK (27-29) what you understand about Vue slots

Vue 100 Q (23-26 Q) What is the nature of the Vue instruction?

Vue 100 Q (18-22 q) Tell us about your understanding of the Vue life cycle

Vue100 q (questions 6-17)

Vue100 asks (question 5) why can’t v-for’s key be index?

Vue100 Q (Question 4) Tell me about a Vue modifier you’ve used in your daily life

Vue100 Q (2-3 Q) When is the. Sync modifier used?

Question (1) How to achieve bidirectional binding without using V-Model?