前言:element ui 中有些 demo 使用了 vue 的 VNode,可是 demo 畢竟不全,因此想要了解 VNode 究竟是什麼,如何寫出符合本身業務的代碼。html
vue 官網介紹:渲染函數 & JSXvue
這裏涉及到 createElement 函數。這個函數的返回值就是一個 VNode 對象。express
createElement
到底會返回什麼呢?其實不是一個實際的 DOM 元素。它更準確的名字多是 createNodeDescription
,由於它所包含的信息會告訴 Vue 頁面上須要渲染什麼樣的節點,及其子節點。咱們把這樣的節點描述爲「虛擬節點 (Virtual Node)」,也常簡寫它爲「VNode」。「虛擬 DOM」是咱們對由 Vue 組件樹創建起來的整個 VNode 樹的稱呼。數組
虛擬 DOM。Vue 經過創建一個虛擬 DOM 對真實 DOM 發生的變化保持追蹤。dom
使用 JSX 語法。異步
接下來你須要熟悉的是如何在 createElement
函數中生成模板。這裏是 createElement
接受的參數:async
// @returns {VNode} createElement( // {String | Object | Function} // 一個 HTML 標籤字符串,組件選項對象,或者 // 解析上述任何一種的一個 async 異步函數。必需參數。 'div', // {Object} // 一個包含模板相關屬性的數據對象 // 你能夠在 template 中使用這些特性。可選參數。 { // (詳情見下一節) }, // {String | Array} // 子虛擬節點 (VNodes),由 `createElement()` 構建而成, // 也可使用字符串來生成「文本虛擬節點」。可選參數。 [ '先寫一些文字', createElement('h1', '一則頭條'), createElement(MyComponent, { props: { someProp: 'foobar' } }) ] )
在 VNode 數據對象中,下列屬性名是級別最高的字段。該對象也容許你綁定普通的 HTML 特性,就像 DOM 屬性同樣,好比 innerHTML
(這會取代 v-html
指令)。ide
{ // 和`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', // 若是你在渲染函數中向多個元素都應用了相同的 ref 名, // 那麼 `$refs.myRef` 會變成一個數組。 refInFor: true }