vue template engine and rendering mechanism

Template engine

vue how to parse template, instructions how to deal with

problem:

What template
render function
render function and vdom

What is Template

<div id='app'>
  <div>
    <input v-model="title"/>
    <button v-on:click="add">submit</button>
  </div>
  <ul>
    <li v-for="item in list">
      {{item}}
    </li>
  </ul>
</div>

This is a template

So what template is it?

  1. Nature is a string, the string is present, just like html
  2. Logical, such as judges, these cycles, such as v-if, v-for and so on, how it will be logical, there is no logic before writing html
  3. And html format like, but there is a big difference. First of html syntax is not recognized in the v-if, v-for these. The second is html static, no logic, VUE is dynamic, logical. They are just like the format
  4. But in the end still have to convert html template to be displayed.

So how did it do it?

First final template must be converted into js code, because:

  • Template logic, we have v-if, v-for. It must be implemented (Turing-complete language) to use js
  • To render the template into html page, must be implemented in order to use js

Therefore, the template eventually be converted into a js function (render function, that is, rendering function)

First, understand the next with

var obj = {
  name: 'zhangsan',
  age: 20,
  getAddress: function(){
    alert('beijing');
  }
}

// 不用with
function fn(){
  alert(obj.name);
  alert(obj.age);
  obj.getAddress();
}
fn();

// 使用width
function fn1(){
  with(obj){
    alert(name);
    alert(age);
    getAddress();
  }
}
fn1();

In the actual development, try not to use with.

fn is our normal use.

fn1 with the use of.

Two is the same effect, with the inside with, who do not write property, who is uniform, with a wrap.
The readability may not be so strong.

render function

template template render function obtained by Compile compile.

Compiler can compile into parse, optimize and generate three stages, ultimately need render function.

compile the compilation process at this stage may not be necessary to fully grasp, only you need to understand the general process can be resolved.

Simple example

We look at some simple template

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="../lib/vue-2.4.0.js"></script>
	</head>
	<body>
		<div id="app">
		  <p>{{price}}</p>
		</div>

		<script type="text/javascript">
			var vm = new Vue({
				el: '#app',
				data: {
					price:100
				}
			})
		</script>
	</body>
</html>

Pick out the template

<div id="app">
	<p>{{price}}</p>
</div>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="./vue-2.5.13.js"></script>
</head>
<body>
    <div id="app">
        <p>{{price}}</p>
    </div>

    <script>
	/**
	* _c : 创建dom标签
	* _v : 创建文本节点
	* _s : toString
	*/
        var vm = new Vue({
            el: '#app',
            data: {
                price: 100
            }
        })
		
		// 这个模板最终生成的函数是下面这个
        // 以下是手写的 render 函数
        function render() {
            with(this) {  // this 就是 vm
                return _c(
                    'div',
                    {
                        attrs: {'id': 'app'}
                    },
                    [
                        _c('p', [_v(_s(price))])
                    ]
                )
            }
        }
		
		// 把函数翻译一下,也就是不用 with
        function render1() {
            return vm._c(
                'div',
                {
                    attrs: {'id': 'app'}
                },
                [
                    vm._c('p', [vm._v(vm._s(vm.price))])
                ]
            )
        }

    </script>
</body>
</html>

This this is vm this instance, this _c is vm._c, dom used to create labels.

The first parameter is a div.

The second parameter is the object, which objects have attributes.

The third parameter is an array, the array there is only one element, this _c certainly vm._c.

The _c first parameter is p, the second parameter is an array, which is an array, _v (_s (price)), and there's price is certainly vm.price, is data.price.

Then in front of the _s is vm._s, is toString function.

_v also vm._v, used to create the text node.

to sum up:

All template information is contained in the render function.

this即vm

price即this.price即vm.price即data.price。

_c That this._c namely vm._c

vm

todo-list demo a render function

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <!-- 模板 -->
  <div id="app">
    <input v-model='title'/>
    <button v-on:click='add'>submit</button>
    <ul v-for='item in list'>
      {{item}}
    </ul>
  </div>
    
  <!-- 源码 -->
  <script src="./vue-2.6.10.js"></script>
  <script>
    var data = {
      title: '',
      list: []
    }
    // 初始化 vue 实例
    var vm = new Vue({
      el: '#app',
      data: data,
      methods: {
        add: function(){
          this.list.push(this.title);
          this.title = ''
        }
      }
    })
  </script>
</body>
</html>

Then through this example, look at vue render function of what it was like, search for the source code.render, then print it out.

This is above the corresponding template render function.

with(this) {
	return _c('div', {
			attrs: {
				"id": "app"
			}
		},
		[
			_c('input', {
				directives: [{ // 当title发生变化,会赋值给value,从而响应到input
					name: "model",
					rawName: "v-model",
					value: (title),
					expression: "title"
				}],
				domProps: {
					"value": (title)
				},
				on: { // v-model相关  input 里面的数据改变,事件监听到,会赋值给 title
					"input": function($event) {
						if ($event.target.composing) return;
						title = $event.target.value
					}
				}
			}),
			_v(" "),
			_c('button', {
					on: {
						// 绑定 click 事件
						"click": add
					}
				},
				[_v("submit")]
			),
			_v(" "),
			_l(
				// v-for相关
				(list),
				function(item) {
					return _c('ul', [_v("\n " + _s(item) + "\n ")])
				}
			)
		], 2)
}

This is the demo corresponding to the render function.

When creating the input of the second argument there directives. Called the command, the command name is model. value is the title, which is vm.title.

Behind _v ( ''), _ v represents the creation of text nodes, mainly input and button have a wrap, wrap if not, there would be _v to create an empty text nodes.

_l returns an array of return for the list li tag.

Now according todo-list demo of the render function, review the render function:

  • v-model is how to achieve?
  • v-on is how to achieve?
  • v-for is how to achieve?

How to render -vue template is rendered as html

The foregoing has solved the problem of "logic" of the template (v-for v-if)

Generate html template remaining issues of

In addition, what vm._c that? render function returns what?

Brush up on knowledge vdom

Here vm._c with snabbdom inside h () function is very similar.

vm._c returned vnode. Then render function returns also vnode.

It can be understood:

  • vm._c fact, equivalent to the h function snabbdom
  • After the render function is executed, it returns the vnode

How vue template is rendered as html

vm._update(vnode) {
  const prevVnode = vm._vnode;
  vm._vnode = vnode;
  if(!prevVnode){
    vm.$el = vm._patch_(vm.$el, vnode); // 第一次没有值
  } else {
    vm.$el = vm._patch_(prevVnode, vnode); // 有值的情况
  }
}

function updateComponent(){
  // vm._render即上面的render函数,返回vnode
  vm._update(vm._render())
}

render function and vdom

  • updateComponent the patch is implemented in vdom
  • First page rendering execution updateComponent
  • In each modification data attributes performed updateComponent

Asked Questions

What templates are?

Template: string, logical, variable ...... embedded JS

Templates must be converted to JS code (logical, rendering html, JS variables)

render function execution is returned vnode

updateComponent

  • updateComponent the patch is implemented in vdom
  • First page rendering execution updateComponent
  • In each modification data attributes performed updateComponent

Supplementary: vue Throughout the implementation process easy instructions

  • The first step: to render template parsing function
  • Step two: Responsive start listening
  • The third step: the first rendering, display the page and binding dependencies
  • Step Four: attribute change data, trigger rerender

1. resolve to render the template function

  • Use with
  • All information template render function are included
  • Template used in the attribute data, have become a JS variable
  • Template v-model v-for v-on have become the logical JS
  • render function returns the vnode

2. Responsive start listening

  • Object.defineProperty
  • The data on the properties of the agent to vm

3. The first time rendering, display the page and binding dependencies

  • Initial rendering, execution updateComponent, execution vm._render ()
  • Render function execution, accesses data in the data
  • It will be responsive to listen to the get method
  • Execution updateComponent, the patch will come vdom method
  • The patch vnode rendered DOM, for the first time rendering is complete

4. data attribute change, triggering rerender

  • Modify the properties, being responsive to the monitored set
  • set the execution updateComponent
  • updateComponent re-run vm._render ()
  • And the resulting vnode prevVnode, by comparing patch
  • Render to the html

Guess you like

Origin www.cnblogs.com/chrislinlin/p/12587723.html