版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第8章渲染函數(shù)
課程目標(biāo)需要有JavaScript的完全編程的能力了解createElement方法及參數(shù)使用使用渲染函數(shù)實現(xiàn)v-if,v-for,v-model及slot插槽,作用域插槽。2課程內(nèi)容
什么是渲染函數(shù)使用渲染函數(shù)createElement方法VNodes必須唯一使用JavaScript代替模板功能38.1渲染函數(shù)
4Vue渲染函數(shù)就是Render函數(shù),Render函數(shù)會返回一個VNode,VNode就是一個JavaScript對象,DOM的映射。要想理解Vue渲染函數(shù),首先需要了解Vue的虛擬DOM。
8.1.1
從虛擬DOM了解Vue渲染函數(shù)
虛擬DOM的工作是將瀏覽器DOM節(jié)點的所有信息映射到一個JavaScript對象上。因為JavaScript本身是很快的,但是DOM操作本身很慢。如果把DOM的信息映射到JavaScript對象上,至少應(yīng)當(dāng)獲取DOM信息時不需要遍歷DOM,而DOM的操作一直是JavaScript優(yōu)化的重點。使用虛擬DOM,程序員不需要自己操作DOM,關(guān)于DOM的操作都會由虛擬DOM完成,而虛擬DOM一定會以最優(yōu)方案來進行操作,所以虛擬DOM的重點是構(gòu)建一個瀏覽器DOM的信息拷貝樹,拷貝樹里必須包含所有DOM節(jié)點的拷貝節(jié)點,這個拷貝節(jié)點叫作VNode。
58.1渲染函數(shù)
6關(guān)于虛擬DOM的好處還有一個就是Vue會把所有的DOM操作緩存到一個隊列,這種在緩沖時去除重復(fù)數(shù)據(jù),可以避免不必要的計算和DOM操作非常重要。如何創(chuàng)建VNode,可以自己創(chuàng)建VNode,然后Vue將程序員創(chuàng)建的VNode更新到真實DOM上,這樣更自由權(quán)限更大,創(chuàng)建VNode的方法createElement。8.1.2為什么使用渲染函數(shù)通過下面的案例發(fā)現(xiàn):level顯示不同級別的標(biāo)題中插入錨定元素,需要重復(fù)使用<slot></slot>來實現(xiàn)內(nèi)容分發(fā)。雖然模板在大多數(shù)組件中都非常好用,但是這里并不簡潔,為了解決這個問題,Vue提供了渲染函數(shù)
78.<divid="app">9. <h1>10. <aname="hello-world"href="#hello-world">11. Helloworld!12. </a>13. </h1>14. <anchored-heading:level="1">15. <aname="title"href="#title">16. Helloworld!17. </a>18. </anchored-heading>19. </div>20. <scripttype="text/x-template"id="anchored-heading-template">21. <div>22. <h1v-if="level===1">23. <slot></slot>24. </h1>25. <h2v-if="level===2">26. <slot></slot>27. </h2>28. <h3v-if="level===3">29. <slot></slot>30. </h3>31. <h4v-if="level===4">32. <slot></slot>33. </h4>34. <h5v-if="level===5">35. <slot></slot>36. </h5>37. <h6v-if="level===6">38. <slot></slot>39. </h6>40. </div>41. </script>42. <scriptsrc="../js/vue.js"></script>43. <script>44. Vponent('anchored-heading',{45. template:'#anchored-heading-template',46. props:{47. level:{48. type:Number,49. required:true50. }51. }52. })53. newVue({54. el:'#app'55. })56. </script>8.1.3
什么是渲染函數(shù)Vue推薦在絕大多數(shù)情況下使用template來創(chuàng)建HTML。然而在一些場景中,需要JavaScript的完全編程的能力,這就需要使用render函數(shù)。
8Vue.component('組件名',{render:function(createElement){returncreateElement(參數(shù))}})【例8-2】使用渲染函數(shù)
9<metacharset="UTF-8">.<title>斤斗云在線課堂</title></head><body><divid="app"><h1><aname="hello-world"href="#hello-world">Helloworld!</a></h1><anchored-heading:level="1"><aname="title"href="#title">Helloworld!</a></anchored-heading><anchored-heading:level="2"><aname="title"href="#title">Helloworld!</a></anchored-heading><anchored-heading:level="3"><aname="title"href="#title">Helloworld!</a></anchored-heading>10<scriptsrc="../js/Vue.js"></script><script>Vue.component('anchored-heading',{template:'#anchored-heading-template',render:function(createElement){returncreateElement('h'+this.level,//tagname標(biāo)簽名稱this.$slots.default//子組件中的陣列)},props:{level:{type:Number,required:true})newVue({el:'#app'})</script></body></html>在組件中使用props,父組件傳遞參數(shù)level給子組件,同時還做了props驗證,level必須是Number類型。不再使用slot插槽向組件中分發(fā)內(nèi)容,使用$slots.default把子元素顯示出來。8.2createElement方法createElement方法,通過render函數(shù)的參數(shù)傳遞進來。一般情況下如:createElement(tag,{},[])或者createElement(tag,{},String),不過接收的參數(shù)不一樣,后面兩個參數(shù)都是可選的,總共有三個參數(shù)。118.2.1createElement參數(shù)【例8-3】createElement方法必須參數(shù)-{String|Object|Function}12<elem></elem></div><script>
Vue
.
component(‘elem’,
{
render:
function(createElement)
{
return
createElement(‘div’);//一個HTML標(biāo)簽字符/*return
createElement({
template:
‘<div></div>’
//組件選項對象});*/
/*varfunc
=
function()
{
return
{template:
‘
<div></div>’}
};
return
createElement(
func());//一個返回HTML標(biāo)簽字符或組件選項對象的函數(shù)*/}
});
new
Vue({
el:
'
#app
'
});</script></
body></html>【例8-4】createElement方法第二個參數(shù)
-{Object}13
<meta
charset="UTF-8"><titlexrender</title>
<script
src-"-./js/Vue.
js“></script><
/head><body>
<div
id="app">
<elem></elem></div><script>
Vue.
component(‘elem’,
{
render:
functi
on(
createElement)
{
return
createE
lement(‘div’,
{'class':
{
foo:
true,bar:
true
},
style:
{
color:
'gray',fontSize:’
14px'
},
attrs:
{
8.2.2實例化Vue對象、
運行后在頁面上渲染了一個div標(biāo)簽,并且增加了id、class屬性,style行內(nèi)樣式及innerHTML的內(nèi)容如圖8-5所示。14【例8-5】createElement方法第三個參數(shù)-{String|Array}15<body>
<div
id="
app">
<elem></elem></div><script>
Vue
.
component('elem',
(
render:
function(
createElement)
{
var
self
=
this;
return
createElement(
‘div’,
[//由createElement函數(shù)構(gòu)建而成的數(shù)組
createElement(‘h1’,
‘主標(biāo)’
),//createElement函數(shù)返回Vnode對象createElement(‘h2’,
‘副標(biāo)'
)
]);
};
new
Vue({
el:
'
#app'
});</script></body>
16運行后在頁面上渲染了一個<div>標(biāo)簽,并渲染了兩個標(biāo)題對象<h1>、<h2>如圖8-6所示。
使用模板與Render函數(shù)對比
17
模板寫法更簡單、可讀。
模板開發(fā)效率是第一位。模板使用webpack編譯,模板都會被預(yù)編譯為Render函數(shù)。8.2.3
VNodes必須唯一官方提示VNodes必須唯一,就是同一個VNode只能用在一個地方。這里的myParagraphVNode,被使用于div中的兩個VNode,這種用法是不行的,要想使用只能創(chuàng)建兩個相同的VNode對象,而不是這樣指向同一個VNode對象。18render:function(createElement)(varmyParagraphVNode.createElement('p','hi')returncreateElement('div',[myParagraphVNode,myParagraphVNode])8.3使用JavaScript代替模板功能在使用Vue模板時在模板中靈活使用v-if、v-for、v-model等指令和<slot>插槽。但在Render函數(shù)中是沒有提供專用的API。如果在Render函數(shù)中使用這些,需要使用原生的JavaScript來實現(xiàn)
198.3.1v-if和v-for
在Render函數(shù)中可以使用if/else和map來實現(xiàn)template中的v-if和v-for。換成Render函數(shù),可以這樣寫:20<ul
v-if="items
.length">
<li
v-for="item
in
items">{{item
}}</li></ul>
<p
v-else>No
items
found.</p>Vue.
component('
item-list',
{
props:
['items
'],
render:
function
(
createElement
){
if
(this.
items.
length)
{
return
createElement('ul',
this.
items
.
map((item)
=>{
return
createEl
ement(
'
item"
))))
}else
{
return
createElement(
'p',
'No
items
found.
"
)
}}}})8.3.2v-model【例8-5】使用Render函數(shù)實現(xiàn)v-model指令<body><divid="app"><el-input:name="name"@input="val=>name=val"></el-input><div>您學(xué)習(xí)的平臺是:{{name}}</div></div><script>Vue.component('el-input',{render:function(createElement){varself=this;returncreateElement('input',{domProps:{value:self.name},on:{input:function(event){self.$emit('input',event.target.value);.}}}),實現(xiàn)數(shù)據(jù)雙向綁定8.3.3slot插槽【例8-6】this.$slots獲取VNodes列表中的靜態(tài)內(nèi)容<body><divid="app"><blog-post><h1slot="header"><span>可以從this.$slots獲取VNodes列表中的靜態(tài)內(nèi)容</span></h1><p>這里是一個段落</p><pslot="footer">版權(quán)所有</p><p>這里是另一個段落</p></blog-post></div><script>Vue.component('blog-post',{render:function(createElement){varheader=this.$slots.header,//返回由VNode組成的數(shù)組body=this.$slots.default,footer=this.$slots.footer;returncreateElement('div',[createElement('header',header),createElement('main',body),createElement('footer',footer)])}});newVue({el:'#app'this.$slots.header獲取header插槽的值,this.$slots.default獲取插槽中的默認值8.3.4作用域插槽【例8-7】this.$scopedSlots作用域插槽<body><divid="app"><ele><templatescope="props"><
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025中國生物質(zhì)成型燃料產(chǎn)業(yè)發(fā)展報告-中國產(chǎn)業(yè)發(fā)展促進會
- 2026年反腐知識競賽試卷含答案(共五套)
- 2026年智能會議系統(tǒng) (視頻會議無線投屏)項目公司成立分析報告
- 2026年智能音頻轉(zhuǎn)換器項目評估報告
- 2026年反電信詐騙知識競賽試題卷及答案(一)
- 四川省宜賓市第二中學(xué)校2025-2026學(xué)年八年級上學(xué)期期中語文試題(無答案)
- 2026年智能熱水器清洗設(shè)備項目公司成立分析報告
- 2026年自適應(yīng)遠近光燈項目公司成立分析報告
- 《GA 2316-2024警服 移民管理警察夏執(zhí)勤褲》專題研究報告
- 教師職稱評審檔案管理制度
- 抹灰層陰陽角方正度控制技術(shù)
- 中國特色社會主義知識點總結(jié)中職高考政治一輪復(fù)習(xí)
- 五年級數(shù)學(xué)下冊寒假作業(yè)每日一練
- 企業(yè)管理的基礎(chǔ)工作包括哪些內(nèi)容
- 學(xué)?!?530”安全教育記錄表(2024年秋季全學(xué)期)
- 鋁合金門窗工程技術(shù)規(guī)范
- 食材配送服務(wù)方案投標(biāo)文件(技術(shù)標(biāo))
- 室性心律失常
- 《2024消費者金融知識學(xué)習(xí)偏好及行業(yè)宣教洞察報告》
- 橫穿公路管道施工方案
- 中國高血壓防治指南(2024年修訂版)解讀課件
評論
0/150
提交評論