vue為什么要求組件模板只能有一個(gè)根元素
這個(gè)問題需要從兩個(gè)方面來說起:
1.new Vue({el:'#app'})
2.單文件組件中寓辱,template下的元素div
一、當(dāng)我們實(shí)例化Vue的時(shí)候划提,填寫一個(gè)el選項(xiàng)桨吊,來指定我們的SPA入口:
let vm = new Vue({
el:'#app'
})
同時(shí)我們也會(huì)在body里面新增一個(gè)id為app的div
<body>
<div id='app'></div>
</body>
這很好理解车吹,就是為vue開啟一個(gè)入口瞻赶,那我們不妨來想想谆棺,如果我在body下這樣
<body>
<div id='app1'></div>
<div id='app2'></div>
</body>
Vue其實(shí)并不知道哪一個(gè)才是我們的入口叹螟,因?yàn)閷?duì)于一個(gè)入口來講魄宏,這個(gè)入口就是一個(gè)‘Vue類'秸侣,Vue需要把這個(gè)入口里面的所有東西拿來渲染,處理宠互,最后再重新插入到dom中味榛。
如果同時(shí)設(shè)置了多個(gè)入口,那么vue就不知道哪一個(gè)才是這個(gè)‘類'予跌。
二搏色、當(dāng)我們?cè)趙ebpack搭建的vue開發(fā)環(huán)境下,使用單文件組件時(shí)券册,你可能會(huì)這樣:
<template>
<div class='component'></div>
</template>
那這里為什么template下也必須有且只能有一個(gè)div呢频轿?
這里我們要先看一看template這個(gè)標(biāo)簽垂涯,這個(gè)標(biāo)簽是HTML5出來的新標(biāo)簽,它有三個(gè)特性:
1.隱藏性:該標(biāo)簽不會(huì)顯示在頁面的任何地方航邢,即便里面有多少內(nèi)容耕赘,它永遠(yuǎn)都是隱藏的狀態(tài);
2.任意性:該標(biāo)簽可以寫在頁面的任何地方翠忠,甚至是head鞠苟、body、sciprt標(biāo)簽內(nèi)秽之;
3.無效性:該標(biāo)簽里的任何HTML內(nèi)容都是無效的当娱,不會(huì)起任何作用;
但是呢考榨,你可以通過innerHTML來獲取到里面的內(nèi)容跨细。
知道了這個(gè),我們?cè)賮砜?vue的單文件組件河质。其實(shí)本質(zhì)上冀惭,一個(gè)單文件組件,本質(zhì)上(我認(rèn)為)會(huì)被各種各樣的loader處理成為.js文件(因?yàn)楫?dāng)你import一個(gè)單文件組件并打印出來的時(shí)候掀鹅,是一個(gè)vue實(shí)例)散休,通過template的任意性我們知道,template包裹的HTML可以寫在任何地方乐尊,那么對(duì)于一個(gè).vue來講戚丸,這個(gè)template里面的內(nèi)容就是會(huì)被vue處理為虛擬dom并渲染的內(nèi)容,導(dǎo)致結(jié)果又回到了開始 :既然一個(gè).vue單文件組件是一個(gè)vue實(shí)例扔嵌,那么這個(gè)實(shí)例的入口在哪里限府?
如果在template下有多個(gè)div,那么該如何指定這個(gè)vue實(shí)例的根入口痢缎?
為了讓組件能夠正常的生成一個(gè)vue實(shí)例胁勺,那么這個(gè)div會(huì)被自然的處理成程序的入口。
通過這個(gè)‘根節(jié)點(diǎn)'独旷,來遞歸遍歷整個(gè)vue‘樹'下的所有節(jié)點(diǎn)署穗,并處理為vdom,最后再渲染成真正的HTML势告,插入在正確的位置
那么這個(gè)入口蛇捌,就是這個(gè)樹的‘根',各個(gè)子元素咱台,子組件络拌,就是這個(gè)樹的‘枝葉',而自然而然地回溺,這棵‘樹'春贸,就是指一個(gè)vue實(shí)例了混萝。