做者:Joshua Bemenderfer
譯者:前端小智
來源:vuejsbook.com
點贊再看,養成習慣本文
GitHub
https://github.com/qq44924588... 上已經收錄,更多往期高贊文章的分類,也整理了不少個人文檔,和教程資料。歡迎Star和完善,你們面試能夠參照考點複習,但願咱們一塊兒有點東西。前端
咱們知道 Vue 模板是很是強大的,基本能夠完成咱們平常開發的全部任務。可是,有一些用例,如基於輸入或插槽值建立動態組件方式,render
函數會比模板完成的更好也更出色。vue
用過 React 開發的人對 render
函數應該很是熟悉,由於React組件經過 JSX和 render 函數來構建的。 儘管Vue render
函數也能夠用JSX編寫,但在這裏咱們使用原生 JS方式,由於這樣,咱們能夠更輕鬆地瞭解Vue組件系統的一些基礎。git
值得注意的是,Vue 的模板實際上在編譯時也是會先解析成 render
函數表示方式。 模板只是在render
函數之上提供了一個方便且熟悉的語法糖。 儘管 render
函數更強大,但render
函數可讀性不好,相對用的也比較少了。github
帶有 render
函數的組件沒有template
標記或屬性。 相反,該組件定義了一個了名爲render
的函數,該函數接收一個reateElement(renderElement: String | Component, definition: Object, children: String | Array)
參數(因爲某種緣由,一般別名爲h
,歸咎於JSX)並返回使用該函數建立的元素,其餘一切保持不變,來看看事例:面試
export default { data() { return { isRed: true } }, /* * <template> * <div :class="{'is-red': isRed}"> * <p>這是一個 render 事例</p> * </div> * </template> */ // render 中的渲染結果與上面等價 render(h) { return h('div', { 'class': { 'is-red': this.isRed } }, [ h('p', '這是一個 render 事例') ]) } }
Vue 模板具備各類便捷功能,以便向模板添加基本邏輯和綁定功能,如 v-if
、v-for
、v-moel
指令等。 在render
函數中是沒法使用這些指令的。 取而代之的是以純 JS 來實現,對於大多數指令而言,這也是比較簡單的。數組
v-if
用純 JS 實現很簡單,只需圍繞createElement
調用使用 if(expr)
語句便可。微信
v-for
可使用for-of
,Array.map
,Array.filter
等的JS方法中的任何一種來實現。咱們能夠經過很是有趣的方式將它們組合在一塊兒,以實現過濾或狀態切片,而無需計算屬性。dom
例如,有如下 Vue 的模板代碼函數
<template> <ul> <li v-for="pea of pod"> </li> </ul> </template>
能夠用下面的 render
函數來實現上面的效果:工具
render(h) { return h('ul', this.pod.map(pea => h('li', pea.name))); }
咱們知道,v-model
只是bind
屬性與value
的語法糖,並在觸發input
事件時設置數據屬性。可是,在render
函數沒有這樣的簡寫,咱們須要本身實現。
假設,在 Vue 中,咱們有以下的結構:
<template> <input v-model='myBoundProperty'/> </template>
上面代碼等價於:
<template> <input :value="myBoundProperty" @input="myBoundProperty = $event.target.value"/> </template>
在 render 函數中能夠用下面方式來實現上面的代碼:
render(h) { return h('input', { domProps: { value: this.myBoundProperty }, on: { input: e => { this.myBoundProperty = e.target.value } } }) }
attribute
和property
這兩種類型的綁定被放在元素定義中,如arttrs
、props
和domProps
( value
和innerHTML
之類的東西)。
render(h) { return h('div', { attrs: { // <div :id="myCustomId"> id: this.myCustomId }, props: { // <div :someProp="someonePutSomethingHere"> someProp: this.someonePutSomethingHere }, domProps: { // <div :value="somethingElse"> value: this.somethingElse } }); }
須要注意的是,對於 class
和style
的綁定是直接在定義的根進行處理,而不是做爲attrs
,props
或domProps
處理。
render(h) { return h('div', { // 「類」是JS中的保留關鍵字,所以必須引用它。 'class': { myClass: true, theirClass: false }, style: { backgroundColor: 'green' } }); }
對事件處理程也是直接添加到元素定義中 on
定義
render(h) { return h('div', { on: { click(e) { console.log('I got clickeded!') } } }); }
事件的修飾符能夠在處理程序內部實現:
.stop -> e.stopPropagation()
.prevent -> e.preventDefault()
.self -> if (e.target !== e.currentTarget) return
鍵盤修飾符
.[TARGET_KEY_CODE]
-> if (event.keyCode !== TARGET_KEY_CODE) return
.[MODIFIER]
-> if (!event.MODIFIERKey) return
Slots
能夠經過this.$slots
做爲createElement()
節點的數組來訪問插槽。
做用域插槽存儲在this.$scopedSlots[scope](props:object)
中,做爲返回createElement()
節點數組的函數。
代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug。
原文:https://vuejsbook.com/introdu...
文章每週持續更新,能夠微信搜索「 大遷世界 」第一時間閱讀和催更(比博客早一到兩篇喲),本文 GitHub https://github.com/qq449245884/xiaozhi 已經收錄,整理了不少個人文檔,歡迎Star和完善,你們面試能夠參照考點複習,另外關注公衆號,後臺回覆福利,便可看到福利,你懂的。