vue中子组件有template这个属性,在里面定义的内容会把子组件的标签覆盖,比如:
var rendercom={
//template的内容会把mycom覆盖
template:`<div><h1>render渲染</h1></div>`
}
var vm = new Vue({
el: '#box',
components:{
'mycom':rendercom
}
})
要是在调用处
<div id="box">
<mycom></mycom>
</div>
mycom会被template的<div><h1>render渲染</h1></div>覆盖。
那根组件为什么不能有template呢?其实是有的,但是根组件的el这个属性也相当于template,设置了vue管辖的位置。那如果非要在根组件加上template呢?也是可以的
var vm = new Vue({
el: '#box',
template:`<div><h2>我是根组件template</h2></div>`,
components:{
'mycom':rendercom
}
})
但是根组件的template会把页面全部覆盖,子组件的内容有再多都没用,只会显示根组件的template。那很明显这没有意义。
同样,还有一个与根组件的template属性很像,是render(渲染)属性。
/render函数的返回值也可以替换根组件选中的dom,和template相似,render的形参createElemrnt,用于创建一个虚拟dom,当然形参名称随便。render返回值createElemrnt有两种,两种调用方式,自己构建虚拟dom。或者使用一个组件去描述虚拟dom。
-
自己构建虚拟dom
render:function(createElemrnt){
//虚拟dom标签名,虚拟dom内容
return createElemrnt('h1','我是虚拟的dom');//VNode
// render函数底层会把虚拟dom转化成真实dom
//真实dom很耗费性能
}
,
这个相当于
// var h1=document.createElement('h1');
// h1.innerHTML='我是虚拟的dom';
// document.body.appendChild(h1)
为什么会使用的虚拟DOM?
因为真实的DOM渲染、重绘是很耗费性能,我们可以使用虚拟DOM方式描述一个DOM对象,然后在下次有数据变化后,重新生成一个虚拟DOM,然后使用的 diff 算法让新的和旧的对比,得出差异性(专业术语 patch 补丁),然后做真实DOM操作。
-
使用的一个组件对象去描述虚拟DOM
比如之间举例的那个rendercom子组件,
render:function(createElemrnt){
return createElemrnt(rendercom);
//真实dom很耗费性能
}
这个时候就可以虚拟了这个组件。
还可以简写成
render:h=>h(rendercom)
其实vue的作者还是希望大家把createElemrnt换成h,因为在vuejs底层有这样一个库,通ts语言转化成虚拟dom的,纪念意义吧。

image.png