淺析Vue 中的 render 函數(shù)
render函數(shù)是什么
簡(jiǎn)單的說(shuō),在vue中我們使用模板HTML語(yǔ)法組建頁(yè)面的,使用render函數(shù)我們可以用js語(yǔ)言來(lái)構(gòu)建DOM
因?yàn)関ue是虛擬DOM,所以在拿到template模板時(shí)也要轉(zhuǎn)譯成VNode的函數(shù),而用render函數(shù)構(gòu)建DOM,vue就免去了轉(zhuǎn)譯的過(guò)程。
當(dāng)使用render函數(shù)描述虛擬DOM時(shí),vue提供一個(gè)函數(shù),這個(gè)函數(shù)是就構(gòu)建虛擬DOM所需要的工具。官網(wǎng)上給他起了個(gè)名字叫createElement。還有約定的簡(jiǎn)寫(xiě)叫h,
vm中有一個(gè)方法_c,也是這個(gè)函數(shù)的別名
先看官網(wǎng)對(duì) createElement的介紹
// @returns {VNode} createElement( // {String | Object | Function} // 一個(gè) HTML 標(biāo)簽字符串,組件選項(xiàng)對(duì)象,或者 // 解析上述任何一種的一個(gè) async 異步函數(shù),必要參數(shù)。 'div', // {Object} // 一個(gè)包含模板相關(guān)屬性的數(shù)據(jù)對(duì)象 // 這樣,您可以在 template 中使用這些屬性。可選參數(shù)。 { // (詳情見(jiàn)下一節(jié)) }, // {String | Array} // 子節(jié)點(diǎn) (VNodes),由 `createElement()` 構(gòu)建而成, // 或使用字符串來(lái)生成“文本節(jié)點(diǎn)”??蛇x參數(shù)。 [ '先寫(xiě)一些文字', createElement('h1', '一則頭條'), createElement(MyComponent, { props: { someProp: 'foobar' } }) ] )
就是說(shuō)createElement(params1,params2,params3)接受三個(gè)參數(shù),每個(gè)參數(shù)的類型官方介紹已經(jīng)說(shuō)明
好了,開(kāi)始今天的正文。
本文 GitHub https://github.com/qq44924588... 上已經(jīng)收錄,更多往期高贊文章的分類,也整理了很多我的文檔,和教程資料。歡迎Star和完善,大家面試可以參照考點(diǎn)復(fù)習(xí),希望我們一起有點(diǎn)東西。
我們知道 Vue 模板是非常強(qiáng)大的,基本可以完成我們?nèi)粘i_(kāi)發(fā)的所有任務(wù)。但是,有一些用例,如基于輸入或插槽值創(chuàng)建動(dòng)態(tài)組件方式, render 函數(shù)會(huì)比模板完成的更好也更出色。
用過(guò) React 開(kāi)發(fā)的人對(duì) render 函數(shù)應(yīng)該非常熟悉,因?yàn)镽eact組件通過(guò) JSX和 render 函數(shù)來(lái)構(gòu)建的。 盡管Vue render 函數(shù)也可以用JSX編寫(xiě),但在這里我們使用原生 JS方式,因?yàn)檫@樣,我們可以更輕松地了解Vue組件系統(tǒng)的一些基礎(chǔ)。
值得注意的是,Vue 的模板實(shí)際上在編譯時(shí)也是會(huì)先解析成 render 函數(shù)表示方式。 模板只是在 render 函數(shù)之上提供了一個(gè)方便且熟悉的語(yǔ)法糖。 盡管 render 函數(shù)更強(qiáng)大,但 render 函數(shù)可讀性很差,相對(duì)用的也比較少了。
創(chuàng)建組件
帶有 render 函數(shù)的組件沒(méi)有 template 標(biāo)記或?qū)傩浴?相反,該組件定義了一個(gè)了名為 render 的函數(shù),該函數(shù)接收一個(gè) reateElement(renderElement: String | Component, definition: Object, children: String | Array) 參數(shù)(由于某種原因,通常別名為 h ,歸咎于JSX)并返回使用該函數(shù)創(chuàng)建的元素,其他一切保持不變,來(lái)看看事例:
export default { data() { return { isRed: true } }, /* * <template> * <div :class="{'is-red': isRed}"> * <p>這是一個(gè) render 事例</p> * </div> * </template> */ // render 中的渲染結(jié)果與上面等價(jià) render(h) { return h('div', { 'class': { 'is-red': this.isRed } }, [ h('p', '這是一個(gè) render 事例') ]) } }
render 函數(shù)中如何表示指令
Vue 模板具有各種便捷功能,以便向模板添加基本邏輯和綁定功能,如 v-if 、 v-for 、 v-moel 指令等。 在 render 函數(shù)中是無(wú)法使用這些指令的。 取而代之的是以純 JS 來(lái)實(shí)現(xiàn),對(duì)于大多數(shù)指令而言,這也是比較簡(jiǎn)單的。
v-if
v-if 用純 JS 實(shí)現(xiàn)很簡(jiǎn)單,只需圍繞 createElement 調(diào)用使用 if(expr) 語(yǔ)句即可。
v-for
v-for 可以使用 for-of , Array.map , Array.filter 等的JS方法中的任何一種來(lái)實(shí)現(xiàn)。我們可以通過(guò)非常有趣的方式將它們組合在一起,以實(shí)現(xiàn)過(guò)濾或狀態(tài)切片,而無(wú)需計(jì)算屬性。
例如,有以下 Vue 的模板代碼
<template> <ul> <li v-for="pea of pod"> </li> </ul> </template>
可以用下面的 render 函數(shù)來(lái)實(shí)現(xiàn)上面的效果:
render(h) { return h('ul', this.pod.map(pea => h('li', pea.name))); }
v-model
我們知道, v-model 只是 bind 屬性與 value 的語(yǔ)法糖,并在觸發(fā) input 事件時(shí)設(shè)置數(shù)據(jù)屬性。但是,在 render 函數(shù)沒(méi)有這樣的簡(jiǎn)寫(xiě),我們需要自己實(shí)現(xiàn)。
假設(shè),在 Vue 中,我們有如下的結(jié)構(gòu):
<template> <input v-model='myBoundProperty'/> </template>
上面代碼等價(jià)于:
<template> <input :value="myBoundProperty" @input="myBoundProperty = $event.target.value"/> </template>
在 render 函數(shù)中可以用下面方式來(lái)實(shí)現(xiàn)上面的代碼:
render(h) { return h('input', { domProps: { value: this.myBoundProperty }, on: { input: e => { this.myBoundProperty = e.target.value } } }) }
v-bind
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 } }); }
需要注意的是,對(duì)于 class 和 style 的綁定是直接在定義的根進(jìn)行處理,而不是作為 attrs , props 或 domProps 處理。
render(h) { return h('div', { // “類”是JS中的保留關(guān)鍵字,因此必須引用它。 'class': { myClass: true, theirClass: false }, style: { backgroundColor: 'green' } }); }
v-on
對(duì)事件處理程也是直接添加到元素定義中 on 定義
render(h) { return h('div', { on: { click(e) { console.log('I got clickeded!') } } }); }
事件的修飾符可以在處理程序內(nèi)部實(shí)現(xiàn):
.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 可以通過(guò) this.$slots 作為 createElement() 節(jié)點(diǎn)的數(shù)組來(lái)訪問(wèn)插槽。
作用域插槽存儲(chǔ)在 this.$scopedSlots[scope](props:object)
中,作為返回 createElement() 節(jié)點(diǎn)數(shù)組的函數(shù)。
代碼部署后可能存在的BUG沒(méi)法實(shí)時(shí)知道,事后為了解決這些BUG,花了大量的時(shí)間進(jìn)行l(wèi)og 調(diào)試,這邊順便給大家推薦一個(gè)好用的BUG監(jiān)控工具 Fundebug 。
總結(jié)
到此這篇關(guān)于淺析Vue 中的 render 函數(shù)的文章就介紹到這了,更多相關(guān)Vue render 函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 淺談Vue中render中的h箭頭函數(shù)
- 詳解vue 動(dòng)態(tài)加載并注冊(cè)組件且通過(guò) render動(dòng)態(tài)創(chuàng)建該組件
- Vue render函數(shù)實(shí)戰(zhàn)之實(shí)現(xiàn)tabs選項(xiàng)卡組件
- VUE-Table上綁定Input通過(guò)render實(shí)現(xiàn)雙向綁定數(shù)據(jù)的示例
- Vue render渲染時(shí)間戳轉(zhuǎn)時(shí)間,時(shí)間轉(zhuǎn)時(shí)間戳及渲染進(jìn)度條效果
- vue iview組件表格 render函數(shù)的使用方法詳解
- Vue中render函數(shù)的使用方法
- Vue Render函數(shù)創(chuàng)建DOM節(jié)點(diǎn)代碼實(shí)例
相關(guān)文章
聊聊Vue中provide/inject的應(yīng)用詳解
這篇文章主要介紹了聊聊Vue中provide/inject的應(yīng)用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11基于 Vue 實(shí)現(xiàn)一個(gè)酷炫的 menu插件
本文給大家介紹基于 Vue 實(shí)現(xiàn)一個(gè)酷炫的 menu插件,此篇教程需要大家具備一定的css和vue基礎(chǔ)知識(shí),本文分步驟給大家介紹的非常詳細(xì),需要的朋友參考下吧2017-11-11Vue中函數(shù)防抖節(jié)流的理解及應(yīng)用實(shí)現(xiàn)
這篇文章主要介紹了Vue中函數(shù)防抖節(jié)流的理解及應(yīng)用實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04electron?dialog.showMessageBox的使用案例
Electron?Dialog?模塊提供了api來(lái)展示原生的系統(tǒng)對(duì)話框,本文主要介紹了electron?dialog.showMessageBox的使用案例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08利用Vue+ElementUi實(shí)現(xiàn)評(píng)論功能
這篇文章主要介紹了如何利用Vue+ElementUi實(shí)現(xiàn)評(píng)論功能,結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-04-04vue-cli 3 全局過(guò)濾器的實(shí)例代碼詳解
這篇文章主要介紹了vue-cli 3 全局過(guò)濾器的實(shí)例代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06利用Vue.js框架實(shí)現(xiàn)火車票查詢系統(tǒng)(附源碼)
這篇文章主要介紹了利用Vue.js框架實(shí)現(xiàn)火車票查詢系統(tǒng)的相關(guān)資料,,文中給出了詳細(xì)的介紹與示例代碼,并在文章結(jié)尾給出了完整的項(xiàng)目下載,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-02-02