• 模板引擎-vue中的模板如何被解析,指令如何处理


    模板是什么
    <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>

    这是模板,那么模板是什么呢?

    1、本质是字符串,是以字符串存在的,只不过像html
    2、有逻辑,比如判断,循环这些,如v-if,v-for等,怎么会有逻辑呢,之前写html就没逻辑
    3、与html格式很像,但有很大区别。首先html在语法上是不认识v-if,v-for这些的。第二个是html是静态的,没有逻辑,vue是动态的,有逻辑的。它们只是格式很像
    4、但是最终模板还是要转换为html来显示的。那么他是怎么做到的呢?



    首先模板最终必须转换成js代码,因为:
    第一个模板有逻辑,有v-if,v-for。必须用js才能实现(图灵完备的语言)
    第二个模板要转化为html渲染页面,必须用js才能实现
    因此,模板最终要转换成一个js函数(render函数,也就是渲染函数)
    首先了解下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();

    在实际开发中,尽量不要使用with。fn是我们正常的使用。fn1使用with的情况。两是同样的效果,用with的里面,都不写是谁的属性,是谁统一的用with包起来。这个可读性可能没那么强。

    我们看最简单的一段模板
    <div id="app">
      <p>{{price}}</p>
    </div>

    这个模板最终生成的函数是下面这个

    /**
    * _c : 创建dom标签
    * _v : 创建文本节点
    * _s : toString
    */
    function render(){
      with(this){ // this 就是 vm
        return _c(
          '<div>',
          {
            attrs:{"id":"app"}
          },
          [
            _c('p',[_v(_s(price))])
          ]
        )
      }
    }

    这个this就是vm这个实例,这个_c就是vm._c,用来创建dom标签的。第一个参数是个div。第二个参数是个对象,对象里面有属性。第三个参数是个数组,数组里面只有一个元素,这个_c肯定也是vm._c。这个_c第一个参数是p,第二个参数是个数组,里面也是一个数组,_v(_s(price)),这里面的price肯定是vm.price,就是data.price。然后前面的_s就是vm._s,就是toString函数。_v也是vm._v,用来创建文本节点的。

    总结:
    模板中所有信息都包含在render函数中。
    this即vm
    price即this.price即vm.price即data.price。
    _c即this._c即vm._c



    render函数
    从哪里可以看到render函数?
    看一下todo-list demo的render函数
    <!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>
    然后通过这个例子,看看vue的render函数是什么样子的,在源码搜索code.render,然后打印出来
    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: { // input里面的数据改变,事件监听到,会赋值给 title                 "input": function($event) {                   if ($event.target.composing) return;                   title = $event.target.value                 }               }             }),             _v(" "),             _c('button',               {                 on: {                   "click": add                 }               },               [_v("submit")]             ),             _v(" "),             _l(               (list),               function(item) {                 return _c('ul', [_v(" " + _s(item) + " ")])               }             )         ], 2)       }

    是这个样子的。这就是这个demo所对应的render函数。在创建input的时候第二个参数有个directives。叫做指令,指令名字是model。value是title,也就是vm.title。后面_v(''),_v表示创建文本节点,主要是input和button有个换行,如果不换行,就不会有_v去创建一个空的文本节点。_l就是一个数组,针对list返回li的标签。

  • 相关阅读:
    Java是如何实现平台无关性的
    Java 语法糖详解
    深入分析Java的编译原理
    Java代码的编译与反编译那些事儿
    Java 源码学习系列(三)——Integer
    总结TESTNG与JUNIT的异同
    selenium如何操作cookies实现免登录
    selenium选择弹出窗口
    Selenium+Java(七)Selenium对话框的处理
    Java-控制台接受用户输入数据的方法
  • 原文地址:https://www.cnblogs.com/wzndkj/p/11070202.html
Copyright © 2020-2023  润新知