Render函數詳解

 

一.虛擬dom

  DOM是文檔對象模型(Document Object Model)的簡寫,在瀏覽器中經過js來操做DOM的操做性能不好,因而虛擬Dom應運而生。虛擬Dom就是在js中模擬DOM對象樹來優化DOM操做的一種技術或思路。React和Vue2都使用了虛擬DOM技術,虛擬DOM並非真正意義上的DOM,它做爲一個輕量級的JavaScript對象,在狀態發生變化時,會進行Diff運算,來更新發生變化的DOM,對於未發生變化的DOM節點,不予操做,因爲不是所有重繪,大大提升更新渲染性能。當使用render函數描述虛擬DOM時,vue提供一個函數,這個函數是就構建虛擬DOM所須要的工具。官網上給他起了個名字叫 createElement。還有約定的簡寫叫 h, vm中有一個方法 _c, 也是這個函數的別名。html

 

  在Vue2中,虛擬DOM就是經過一種VNode類表達,每一個DOM元素或組件都對應一個VNode對象。vue

VNode節點解析:express

  • 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。

 

二.CreateElement基本用法

1.基本參數

createElement構成了Vue虛擬DOM的模板,它有3個參數:瀏覽器

// @returns {VNode}
createElement(
  // {String | Object | Function}
  // 一個 HTML 標籤字符串,組件選項對象,或者
  // 解析上述任何一種的一個 async 異步函數。必需參數。
  'div',

  // {Object}
  // 一個包含模板相關屬性的數據對象
  // 你能夠在 template 中使用這些特性。可選參數。
  {
    // (詳情見下一節)
  },

  // {String | Array}
  // 子虛擬節點 (VNodes),由 `createElement()` 構建而成,
  // 也可使用字符串來生成「文本虛擬節點」。可選參數。
  [
    '建立h1標籤',
    createElement('h1', 'Render函數'),
    createElement(MyComponent, {
      props: {
        someProp: 'foobar'
      }
    })
  ]
)

 

2.函數模板各部分含義

a.'div':html節點dom

{String | Object | Function}異步

一個 HTML 標籤字符串,組件選項對象,或者async

解析上述任何一種的一個 async 異步函數,必要參數。ide


b.{}:節點的屬性函數

{Object}

 一個包含模板相關屬性的數據對象

 這樣,您能夠在 template 中使用這些屬性。可選參數。

 詳細屬性:

{
  // 和`v-bind:class`同樣的 API
  // 接收一個字符串、對象或字符串和對象組成的數組
  'class': {
    foo: true,
    bar: false
  },
  // 和`v-bind:style`同樣的 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
  },
  // 僅對於組件,用於監聽原生事件,而不是組件內部使用
  // `vm.$emit` 觸發的事件。
  nativeOn: {
    click: this.nativeClickHandler
  },
  // 自定義指令。注意,你沒法對 `binding` 中的 `oldValue`
  // 賦值,由於 Vue 已經自動爲你進行了同步。
  directives: [
    {
      name: 'my-custom-directive',
      value: '2',
      expression: '1 + 1',
      arg: 'foo',
      modifiers: {
        bar: true
      }
    }
  ],
  // 做用域插槽格式
  // { name: props => VNode | Array<VNode> }
  scopedSlots: {
    default: props => createElement('span', props.text)
  },
  // 若是組件是其餘組件的子組件,需爲插槽指定名稱
  slot: 'name-of-slot',
  // 其餘特殊頂層屬性
  key: 'myKey',
  ref: 'myRef'
}

 

c.[ ]:html節點的子節點

{String | Array}

子節點 (VNodes),由 `createElement()` 構建而成,

或使用字符串來生成「文本節點」。可選參數。

 

3.使用JavaScript代替模板功能

  在Render函數中,再也不須要Vue內置的指令,好比v-ifv-for。不管要實現什麼功能,均可以使用原生JavaScript。render函數裏沒有與v-model對應的API,須要本身來實現邏輯。

  對於事件修飾符和按鍵修飾符,基本須要本身實現:

修飾符 對應的句柄
.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
}
View Code
相關文章
相關標籤/搜索