Render函数

Render函数

Vue2与Vue1最大的区别就在于Vue2使用了虚拟DOM来更新DOM节点,提高渲染性能。html

虚拟DOM

React和Vue2都使用了虚拟DOM技术,虚拟DOM并非真正意义上的DOM,而是一个轻量级的JavaScript对象,在状态发生变化时,虚拟DOM会进行Different运算,来更新只须要被替换的DOM,而不是所有重绘。数组

与DOM操做相比,虚拟DOM是基于JavaScript计算的,因此开销会小不少。async

在Vue2中,虚拟DOM就是经过一种VNode类表达,每一个DOM元素或组件对对应一个VNode对象。函数

VNodeData节点解析:性能

  • children 子节点,数组,也是VNode类型。
  • text 当前节点的文本,通常文本节点或注释节点会有该属性。
  • elm 当前虚拟节点对应的真实的DOM节点。
  • ns 节点的namespace
  • content 编译做用域
  • functionalContext 函数化组件的做用域
  • key 节点的key属性,用于做为节点的标识,有利于patch的优化
  • componentOptions 建立组件实例时会用到的选项信息。
  • child 当前节点对应的组件实例。
  • parent 组件的占位节点。
  • raw 原始html
  • isStatic 静态节点的标识
  • isRootInset 是否做为根节点插入,被<transition>包裹的节点,该属性的值为false
  • isConment 当前节点是不是注释节点。
  • isCloned 当前节点是否为克隆节点。
  • isOnce 当前节点是否有v-once指令。

VNode主要能够分为如下几类:优化

  • TextVNode 文本节点。
  • ElementVNode 普通元素节点。
  • ComponentVNode 组件节点。
  • EmptyVNode 没有内容的注释节点。
  • CloneVNode 克隆节点,能够是以上任意类型的节点,惟一的区别在于isCloned属性为true

Render函数经过createElement参数来建立虚拟DOM,结构精简。其中,访问slot的用法,使用场景集中在Render函数this

<p data-height="265" data-theme-id="0" data-slug-hash="wXozpg" data-default-tab="html,result" data-user="whjin" data-embed-version="2" data-pen-title="Vue-render函数" class="codepen">See the Pen Vue-render函数 by whjin (@whjin) on CodePen.</p>
<script async src="https://static.codepen.io/ass...;></script>spa

createElement用法

基本参数

createElement构成了Vue虚拟DOM的模板,它有3个参数:code

createElement(
    //{String | Object | Function}
    //一个HTML标签,组件选项,或一个函数
    //必须return上面其中一个
    'div',
    //{Object}
    //一个对应属性的数据对象,可选
    //能够在template中使用
    //{String | Array}
    //子节点(VNode),可选
    [
        createElement('h1','hello world'),
        createElement(MyComponent,{
            props:{
                someProp:'foo'
            }
        }),
        'bar'
    ]
);

第一个参数必选,能够是一个HTML标签,也能够是一个组件或函数;第二个是可选参数,数据对象,在template中使用。第三个是子节点,也是可选参数,用法一直。component

以前在template中都是在组件的标签上使用v-bind:classv-bind:stylev-on:click这样的指令,在Render函数都将其写在了数据对象中。

约束

全部的组件树中,若是VNode是组件或含有组件的slot,nameVNode必须惟一。

在Render函数里建立了一个cloneVNode的工厂函数,经过递归将slot全部子节点都克隆了一份,并对VNode的关键属性也进行复制。

使用JavaScript代替模板功能

在Render函数中,再也不须要Vue内置的指令,好比v-ifv-for。不管要实现什么功能,均可以使用原生JavaScript。

<p data-height="265" data-theme-id="0" data-slug-hash="eKgVgQ" data-default-tab="html,result" data-user="whjin" data-embed-version="2" data-pen-title="render--v-for" class="codepen">See the Pen render--v-for by whjin (@whjin) on CodePen.</p>
<script async src="https://static.codepen.io/ass...;></script>

map()方法时快速改变数组结构,返回一个新数组。 map常和 filtersort等方法一块儿使用,它们返回的都是新数组。

Render函数里没有与v-model对应的API,须要本身来实现逻辑。

<p data-height="265" data-theme-id="0" data-slug-hash="BVpYdd" data-default-tab="html,result" data-user="whjin" data-embed-version="2" data-pen-title="Vue-render-API" class="codepen">See the Pen Vue-render-API by whjin (@whjin) on CodePen.</p>
<script async src="https://static.codepen.io/ass...;></script>

v-model就是prop:valueevent:input组合使用的一个语法糖,虽然在Render里写起来比较复杂,可是能够自由控制,深刻到更底层。

对于事件修饰符和按键修饰符,基本须要本身实现:

修饰符 对应的句柄
.stop event.stopPropagation()
.prevent event.preventDefault()
.self if(event.target!==event.currentTarget) return
.ente.13 if(event.keyCode!==13) return替换13位须要的keyCode
.ctrl.alt.shift.meta if(!event.ctrlKey) return根据须要替换ctrlKeyaltKeyshiftKeymetaKey

对于事件修饰符.capture.once,Vue提供了特殊的前缀,能够直接写在on的配置里。

修饰符 前缀
.capture !
.once ~
.capture.once.once.capture ~!

写法以下:

on: {
    '!click': this.doThisInCapturingMode,
        '~keyup': this.doThisOnce,
        '~!mouseover': this.doThisOnceInCapturingMode
}

简单模拟聊天发送内容的场景:

<p data-height="265" data-theme-id="0" data-slug-hash="ZRLrPN" data-default-tab="html,result" data-user="whjin" data-embed-version="2" data-pen-title="Vue-模拟聊天发送内容" class="codepen">See the Pen Vue-模拟聊天发送内容 by whjin (@whjin) on CodePen.</p>
<script async src="https://static.codepen.io/ass...;></script>

在Render函数中会大量使用slot,在没有使用slot时会显示一个默认的内容,这部分须要本身实现。

this.$slots.default等于undefined,就说明父组件中没有定义slot,这是能够自定义显示的内容。

相关文章
相关标签/搜索