我們知道 Vue 模板是非常強大的,基本可以完成我們日常開發的所有任務。但是,有一些用例,如基於輸入或插槽值創建動態組件方式,render 函數會比模板完成的更好也更出色。
用過 React 開發的人對 render 函數應該非常熟悉,因為React組件通過 JSX和 render 函數來構建的。儘管Vue render 函數也可以用JSX編寫,但在這裡我們使用原生 JS方式,因為這樣,我們可以更輕鬆地瞭解Vue組件系統的一些基礎。
值得注意的是,Vue 的模板實際上在編譯時也是會先解析成 render 函數表示方式。模板只是在render 函數之上提供了一個方便且熟悉的語法糖。儘管 render 函數更強大,但render函數可讀性很差,相對用的也比較少了。
創建組件
帶有 render 函數的組件沒有template標記或屬性。相反,該組件定義了一個了名為render的函數,該函數接收一個reateElement(renderElement: String | Component, definition: Object, children: String | Array)參數(由於某種原因,通常別名為h,歸咎於JSX)並返回使用該函數創建的元素,其他一切保持不變,來看看事例:
render 函數中如何表示指令
Vue 模板具有各種便捷功能,以便向模板添加基本邏輯和綁定功能,如 v-if、v-for、v-moel指令等。在render函數中是無法使用這些指令的。取而代之的是以純 JS 來實現,對於大多數指令而言,這也是比較簡單的。
v-if
v-if 用純 JS 實現很簡單,只需圍繞createElement調用使用 if(expr)語句即可。
v-for
v-for可以使用for-of,Array.map,Array.filter等的JS方法中的任何一種來實現。我們可以通過非常有趣的方式將它們組合在一起,以實現過濾或狀態切片,而無需計算屬性。
例如,有以下 Vue 的模板代碼
可以用下面的 render 函數來實現上面的效果:
<code>render(h) { return h('ul', this.pod.map(pea => h('li', pea.name)));}/<code>
v-model
我們知道,v-model只是bind屬性與value的語法糖,並在觸發input事件時設置數據屬性。但是,在render函數沒有這樣的簡寫,我們需要自己實現。
假設,在 Vue 中,我們有如下的結構:
<code><template> /<template>/<code>
上面代碼等價於:
在 render 函數中可以用下面方式來實現上面的代碼:
v-bind
attribute和property 這兩種類型的綁定被放在元素定義中,如arttrs、props和domProps( value 和innerHTML之類的東西)。
需要注意的是,對於 class和style的綁定是直接在定義的根進行處理,而不是作為attrs,props或domProps處理。
v-on
對事件處理程也是直接添加到元素定義中 on 定義
特殊屬性
Slots 可以通過this.$slots作為createElement()節點的數組來訪問插槽。
作用域插槽存儲在this.$scopedSlots[scope](props:object) 中,作為返回createElement()節點數組的函數。
原文:https://vuejsbook.com/introduction-to-vue-render-functions-with-examples作者:Joshua Bemenderfer 譯者:前端小智 來源:vuejsbook.com
閱讀更多 前端小智 的文章