一、teleport 介紹
teleport 傳送門組件,提供一種簡潔的方式,可以指定它里面的內容的父元素。通俗易懂地講,就是 teleport 中的內容允許我們控制在任意的DOM中,使用簡單。
使用語法:
<teleport to="body"> <div> 需要創建的內容 </div> </teleport>
to 屬性是指定 teleport 中的內容 加入的DOM元素。可以是標簽名,也可以是 id 或類名。
//標簽名 。上述實例就是加入body元素內,使用的是標簽名。 <teleport to="body"></teleport> //類名。如:to=".className" <teleport to=".className"></teleport> //id名 <teleport to="#idName"></teleport>
1.1、多個 teleport 使用
多個 teleport 傳送門組件可以將內容都掛載到一個目標上,多個 teleport 組件內容就是兄弟節點,先掛載的在前面,后掛載的在后面。
使用如下:
<teleport to="body"> <div class="first"> 第一個掛載元素 </div> </teleport> <teleport to="body"> <div class="second"> 第二個掛載元素 </div> </teleport>
運行結果如圖:

上邊的實例等價於:
<teleport to="body"> <div class="first"> 第一個掛載元素 </div> <div class="second"> 第二個掛載元素 </div> </teleport>
二、為什么使用 teleport
使用 vue 開發時,都是多個組件之間不斷地嵌套,處理元素的樣式或者層級的時候就會變得困難。如我們需要添加一個 modal 模態框或 toast 提示框,如果我們把這樣的框可以從 vue 組件中剝離出來,我們樣式和層級設置起來會更加簡便。
有些同學會想,這直接放到 index.html 中不就好了嗎?另外 modal 、toast 元素需要使用 vue 組件的狀態值,通過狀態控制 modal、toast 的隱藏顯示。如果直接放入 index.html 則狀態控制就復雜了。
所以 teleport 傳送門組件就派上用場了。有點像“哆啦A夢”的任意門,可以把元素傳送到任意的元素內。同時還可以使用 vue 組件內的狀態值控制它。
三、teleport 應用
使用 vite + vue 3創建的項目,具體如何創建項目請查看《什么,你還使用 webpack?別人都在用 vite 搭建項目了》文章。
vue 3的項目創建完成之后,找到index.htm文件,添加:
<div id="newModal"></div>
組件文件內,添加 teleport 組件:
<button @click="showModal" class="btn">打開 modal </button> <!-- to 屬性就是目標位置 --> <teleport to="#newModal"> <div v-if="visible"> <div >我是一個 Modal 框</div> </div> </teleport>
運行結果,我們發現使用的teleport組件,通過 to 屬性,將內容傳送到<div id="newModal"></div>內,該元素與<div id="app"></div>同級。此時 teleport 中的元素隱藏顯示完全由vue組件內的狀態值決定。
四、初學者容易遇到的坑
有些同學在自己的項目內,直接引入了 teleport 傳送門組件,運行以后發現該組件原樣輸出了,並沒有被解析,同時還會報錯。
錯誤信息如下:

vue.runtime.esm.js?2b0e:619 [Vue warn]: Unknown custom element: <teleport> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
然后就在網上各種查解決辦法,最后發現壓根找不到!
根本原因是你使用的還是vue2,不是vue3。有些同學會把 腳手架vue-cli 3創建的項目,當作是 vue3 。vue-cli 2 和 vue-cli 3 創建項目與是否是 vue3 沒有必然聯系的。