vue中子組件有template這個屬性,在里面定義的內(nèi)容會把子組件的標簽覆蓋,比如:
var rendercom={
//template的內(nèi)容會把mycom覆蓋
template:`<div><h1>render渲染</h1></div>`
}
var vm = new Vue({
el: '#box',
components:{
'mycom':rendercom
}
})
要是在調(diào)用處
<div id="box">
<mycom></mycom>
</div>
mycom會被template的<div><h1>render渲染</h1></div>覆蓋。
那根組件為什么不能有template呢?其實是有的,但是根組件的el這個屬性也相當于template,設(shè)置了vue管轄的位置。那如果非要在根組件加上template呢?也是可以的
var vm = new Vue({
el: '#box',
template:`<div><h2>我是根組件template</h2></div>`,
components:{
'mycom':rendercom
}
})
但是根組件的template會把頁面全部覆蓋,子組件的內(nèi)容有再多都沒用,只會顯示根組件的template。那很明顯這沒有意義。
同樣,還有一個與根組件的template屬性很像,是render(渲染)屬性。
/render函數(shù)的返回值也可以替換根組件選中的dom,和template相似,render的形參createElemrnt,用于創(chuàng)建一個虛擬dom,當然形參名稱隨便。render返回值createElemrnt有兩種,兩種調(diào)用方式,自己構(gòu)建虛擬dom。或者使用一個組件去描述虛擬dom。
-
自己構(gòu)建虛擬dom
render:function(createElemrnt){
//虛擬dom標簽名,虛擬dom內(nèi)容
return createElemrnt('h1','我是虛擬的dom');//VNode
// render函數(shù)底層會把虛擬dom轉(zhuǎn)化成真實dom
//真實dom很耗費性能
}
,
這個相當于
// var h1=document.createElement('h1');
// h1.innerHTML='我是虛擬的dom';
// document.body.appendChild(h1)
為什么會使用的虛擬DOM?
因為真實的DOM渲染、重繪是很耗費性能,我們可以使用虛擬DOM方式描述一個DOM對象,然后在下次有數(shù)據(jù)變化后,重新生成一個虛擬DOM,然后使用的 diff 算法讓新的和舊的對比,得出差異性(專業(yè)術(shù)語 patch 補丁),然后做真實DOM操作。
-
使用的一個組件對象去描述虛擬DOM
比如之間舉例的那個rendercom子組件,
render:function(createElemrnt){
return createElemrnt(rendercom);
//真實dom很耗費性能
}
這個時候就可以虛擬了這個組件。
還可以簡寫成
render:h=>h(rendercom)
其實vue的作者還是希望大家把createElemrnt換成h,因為在vuejs底層有這樣一個庫,通ts語言轉(zhuǎn)化成虛擬dom的,紀念意義吧。

image.png