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

Before studying the source code, we need to understand the concept of a few things. What is an AST, what is a Render function, what is a template, etc…

Concept of premise

AST syntax tree

The Abstract Syntax Tree. Abstract syntax tree, using JS language to describe HTML code. The HTML code to screen out the attributes we need, into JS language.

<div id="app" style="color: red">
    <p class="text">The text</p>
</div>// AST syntax tree describes HTML syntax<script>
let root = {
    tag: 'div'.type: 1.attrs: [{name: "id".value: "app" },
    { name"style".value: {color" red"}}].parent: null.children: [{
        tag: 'p'.attrs: [{ name: 'class'.value: 'text'}].parent: root,
        type: 1.children: [{
            text: 'text'.type: 3}}}]]</script>
Copy the code

Template template

Template: HtML-based string template. Precedence over the original HTML template.

Render function

Render: a substitute for a template that is closer to a compiler than a template. In Vue, if render is present, the template template string will not be mounted to the element for rendering.

HTML template, string template, render function comparison

You can take a look at the original use of vue:

<div id="app">
   <ul>
      <li v-for="item in sex" v-if="The item = = = 'male'">{{item}}</li>
    </ul>
</div>
<script>
  let vm = new Vue({
    el: '#app'.data: {
      sex: ["Male"."Male"."Female"."Male"]}})console.log(vm.$options.render);
</script>
Copy the code

Template template:

<div id="app"></div>
<script>
  let vm = new Vue({
    el: '#app'.template:
        ` < ul > < li v - for = "item in sex" v - if = "item = = = 'male'" > {{item}} < / li > < / ul > `.data: {
      sex: ["Male"."Male"."Female"."Male"]}})console.log(vm.$options.render);
</script>
Copy the code

Run the browser, both pages are male characters. But in the template template, writing anything else in HTML is not visible. If a template exists, the content in the template is rendered first.

If you print vm.$options.render on the console, you’ll see something like this:

ƒ anonymous(
) {
with(this){return _c('div', {attrs: {"id":"app"}},[_c('ul',_l((sex),function(item){return (item==='male')? _c('li',[_v(_s(item))]):_e()}),0)]}}Copy the code

This is a bunch of stuff that translates our HTML content into js. Of course, we can also turn this string into the Render function in Vue and try it out in the browser.

<div id="app">hhh</div>
<script>
  let vm = new Vue({
    el: '#app'.data: {
      sex: ["Male"."Male"."Female"."Male"]},render(h) {
      with (this) {
        return _c('div', { attrs: { "id": "app" } }, [_c('ul', _l((sex), function (item) { return (item === 'male')? _c('li', [_v(_s(item))]) : _e() }), 0)])}}})</script>
Copy the code

For render function inside _L, _e, _v and other functions can refer to the function defined in the source code.

target._o = markOnce // v-once
target._n = toNumber  / / number
target._s = toString  // Go to the string json.stringify
target._l = renderList V - for / / cycle
target._t = renderSlot  / / slot slot
target._v = createTextVNode // Text node
target._e = createEmptyVNode / / blank nodes.Copy the code

Another _c function is to create a virtual node (createElement).

It turns out that the Render function replaces the template and takes precedence over the template, which takes precedence over the original HTML.

jsx

Compare that to the long list of things inside Render that we might not understand. The corresponding template is simpler. JSX is supported in Vue because of the Babel plug-in in Vue.

let vm = new Vue({
  el: '#app'.data: {
    sex: ["Male"."Male"."Female"."Male"]},render() {
    return <ul>
      <li v-for="item in sex" v-if="The item = = = 'male'">{{ item }}</li>
    </ul>}})Copy the code

Real DOM

Each element on the page counts as a node. Example:

<div id="app" style="color: red">
    <p class="text">The text</p>
</div>
Copy the code

Virtual DOM

Simplify the DOM node. By rendering function _c, _v and other functions to achieve the object to describe dom operations. Virtual DOM DOM reality to simplify, contains the tag, the data, the key, the children, such as text attributes.

<div id="app" style="color: red">
    <p class="text">The text</p>
</div>/ / virtual dom<script>
let root = {
  tag: 'div'.data: [{ id: 'app'.style: { color: 'red'}}].key:undefined.text:undefined.children:[
    {
        tag: 'p'.key:undefined.text:undefined.data: {class:'text'},
        children: []]}</script>
Copy the code

compile

A brief description of the compilation rendering process:

  • parsinghtmlCharacters will behtmlCharacter = >ASTThe syntax tree
  • You need toASTSyntax tree generates finalrenderfunction
    • Concatenated string
    • increasewith
    • new Function
  • To generate a virtualdom
  • Generate realdom

During compilation, we need to convert the HTML to the AST syntax tree and then to the Render virtual DOM. In fact, normal compilation can also be directly from Render to the virtual DOM. However, in the compilation process of VUE, when transforming into AST, some optimization marks need to be carried out according to the template processing interpolation, instructions, extract the maximum static tree (fixed), and reduce the DOM operation times to the minimum.

AST and virtual DOM (VNode) are both JS languages.

  • The AST appears during compilation. The virtual DOM appears at runtime.
  • The AST is a precursor to the virtual DOM, which becomes the virtual DOM after a series of operations.
  • The virtual DOM has no attrs attribute. The virtual DOM places attrs from the AST in the corresponding node. For example, the style attribute in attR is converted to the style of the element node in the virtual DOM by the corresponding element data.