詳解vue為什么要求組件模板只能有一個(gè)根元素
我是在知乎上看到的這個(gè)問題,轉(zhuǎn)念一想,用了大半年的vue,好像真的沒有了解過:
‘為什么只能有且只有一個(gè)根元素'
于是我花了二十多分鐘去找了一下答案......竟然沒有找到答案....
好的現(xiàn)在我來說說我的理解,如果有不對(duì)的地方歡迎指出。
我覺得這個(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í)例了。
鏈接: https://github.com/haizlin/fe-interview/issues/457
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于Vue中keep-alive的作用及使用方法
keep-alive是Vue的內(nèi)置組件,當(dāng)它包裹動(dòng)態(tài)組件時(shí),會(huì)緩存不活動(dòng)的組件實(shí)例,該組件將不會(huì)銷毀,這篇文章主要介紹了關(guān)于Vue中keep-alive的作用是什么?怎么使用,需要的朋友可以參考下2023-04-04Vue3+TypeScript封裝axios并進(jìn)行請(qǐng)求調(diào)用的實(shí)現(xiàn)
這篇文章主要介紹了Vue3+TypeScript封裝axios并進(jìn)行請(qǐng)求調(diào)用的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04VueTreeselect?參數(shù)options的數(shù)據(jù)轉(zhuǎn)換-參數(shù)normalizer解析
這篇文章主要介紹了VueTreeselect?參數(shù)options的數(shù)據(jù)轉(zhuǎn)換-參數(shù)normalizer解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07vue子組件封裝彈框只能執(zhí)行一次的mounted問題及解決
這篇文章主要介紹了vue子組件封裝彈框只能執(zhí)行一次的mounted問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03vue踩坑記-在項(xiàng)目中安裝依賴模塊npm install報(bào)錯(cuò)
這篇文章主要介紹了vue踩坑記-在項(xiàng)目中安裝依賴模塊npm install報(bào)錯(cuò),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04