第九章.Render函数

9.1 virtual DOM

Virtual DOM 并不是真正意义上的DOM,而是一个轻量级的JavaScript对象,在状态发生变化时,Virtual DOM会进行Diff运算,只需要更新被替换的DOM,而不会全部重绘

virtual DOM运行过程

Object---->Render(生成虚拟节点)----->createElement(h)(基于虚拟节点创建DOM节点)----->diff(状态更新后,进行对比,生成补丁对象)—>patch(遍历补丁对象,更新DOM节点)

vnode类型
  • vnode
    • EmptyVNode : 没有内容的注释节点
    • TextVNode : 文本节点
    • ElementVNode :普通元素节点
    • CloneVNode : 克隆节点
    • ComponentVNode : 组件节点

9.2 Render函数

9.3 createElement用法(Render函数通过createElement来创建virtual DOM)

createElement有三个参数

  • 一个HTML标签,组件选项,或一个函数(必须return一个)

  • 一个对应属性的数据对象(可选)

      {
      	//和v-bind:class一样的API
      	'class': {
      		foo:true,
      		bar:false
      	}
      	//和v-bind:sytle一样的API
      	style: {
      		color:'red',
      		fontSize:14px,
      	}
      	//正常的HTML特性
      	attrs:{
      		id:foo
      	}
      	//组件props
      	props:{
      		myProp:'bar'
      	}
      	//DOM属性
      	domProps:{
      		innerHTML:'baz'
      	}
      	//自定义事件监听器on,不支持v-on:keyup.enter的修饰符
      	//需要手动配置keyCode
      	on:{
      		click:this.clickHandler
      	}
      } 	
    
  • 子节点(可选)

9.3.2 Render函数约束
  • 如果Vnode是组件或含有组件的slot,那么VNode必须唯一(现版本经测试,不唯一,也可以实现多次渲染)
    • VNode是组件:

      	var child = {
      		render: function (createElement) {
      	    return createElement('p', 'text');
      	  }
      	}
      	Vue.component('ele', {
      	  render: function (createElement) {
      	    var childNode = createElement(child);
      	    return createElement('div',
      	      [
      	        childNode,
      	        childNode
      	      ]
      	    );
      	  }
      	});
      
    • VNode是含有组件的slot

             <ele>
               <div>
                 <child></child>
               </div>
             </ele>
      
      
      
            Vue.component('child', {
              render: function (createElement) {
                return createElement('p', 'text')
              }
            });
            Vue.component('ele', {
              render: function (createElement) {
                return createElement('div', [
                  this.$slots.default,
                  this.$slots.default
                ]);
              }
            })
      
    • 正确方式

         	var child = {
            render: function (createElement) {
              return createElement('p', 'text');
            }
      
          }
          Vue.component('ele', {
            render: function (createElement) {
              return createElement('div',
                Array.apply(null, { length: 5 }).map(function () {
                  return createElement(child)
                })
              );
            }
          })
      
9.3.3 利用javascript代替模板功能
  • v-if和v-else

      	<div id="app">
     	    <ele :show="show"></ele>
     	    <button @click="show = !show">切换</button>
       	</div>
    
     	 Vue.component('ele', {
     	    render(createElement) {
     	      if (this.show) {
     	        return createElement('p', 'show的值为True')
     	      } else {
     	        return createElement('p', 'show的值为False')
     	      }
     	    },
     	    props: {
     	      show: {
     	        type: Boolean,
     	        default: false
     	      }
     	    }
     	  })
     	  var app = new Vue({
     	    el: '#app',
     	    data: {
     	      show: false
     	    }
     	  })
    
  • v-for

     	 <div id="app">
     		<my-list :list="list"></my-list>
     	 </div>
    
     	Vue.component('my-list', {
     	    render(createElement) {
     	      var nodes = [];
     	      for (let i = 0; i < this.list.length; i++) {
     	        nodes.push(createElement('p', this.list[i]))
     	      }
     	      return createElement('div', nodes);
     	    },
     	    props: {
     	      list: {
     	        type: Array
     	      }
     	    }
     	  })
     	  var app = new Vue({
     	    el: '#app',
     	    data: {
     	      list: [
     	        '《Vue.js实战》',
     	        '《SpringBoot实战》',
     	        '《Git高手之路》'
     	      ]
     	    }
     	  })
    
  • v-model

      	Vue.component('ele', {
      	    render(createElement) {
      	      var _this = this;
      	      return createElement(
      	        'div',
      	        [
      	          createElement('input', {
      	            domProps: {
      	              value: _this.value
      	            },
      	            on: {
      	              input: function (event) { _this.value = event.target.value }
      	            }
      	          }),
      	          createElement('p', 'value:' + this.value)
      	        ]
      	      )
      	    },
      	    data() {
      	      return {
      	        value: ''
      	      }
      	    },
      	  })
      	  var app = new Vue({
      	    el: '#app',
      	  })
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姑苏_IT

创作不易,谢你打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值