“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?