Teleport 是一種能夠?qū)⑽覀兊哪0逡苿拥?DOM 中 Vue app 之外的其他位置的技術(shù),就有點像哆啦A夢的“任意門”
場景:像 modals,toast 等這樣的元素,很多情況下,我們將它完全的和我們的 Vue 應用的 DOM 完全剝離,管理起來反而會方便容易很多
原因在于如果我們嵌套在 Vue 的某個組件內(nèi)部,那么處理嵌套組件的定位、z-index 和樣式就會變得很困難
另外,像 modals,toast 等這樣的元素需要使用到 Vue 組件的狀態(tài)(data 或者 props)的值
這就是 Teleport 派上用場的地方。我們可以在組件的邏輯位置寫模板代碼,這意味著我們可以使用組件的 data 或 props。然后在 Vue 應用的范圍之外渲染它
Teleport 的使用
準備
快速搭建一個 vue3 的項目
$ npm init vite-app learn-vue3
$ cd learn-vue3
$ npm install
$ npm run dev
復制代碼
用 yarn
$ yarn create vite-app learn-vue3
$ cd learn-vue3
$ yarn
$ yarn dev
復制代碼
打開: http://localhost:3000/,看到如下頁面,說明成功了

toast
index.html 中
<div id="app"></div>
+ <div id="teleport-target"></div>
<script type="module" src="/src/main.js"></script>
復制代碼
src/components/HelloWorld.vue 中,添加如下,留意 to 屬性跟上面的 id 選擇器一致
<button @click="showToast" class="btn">打開 toast</button>
<!-- to 屬性就是目標位置 -->
<teleport to="#teleport-target">
<div v-if="visible" class="toast-wrap">
<div class="toast-msg">我是一個 Toast 文案</div>
</div>
</teleport>
復制代碼
import { ref } from 'vue';
export default {
setup() {
// toast 的封裝
const visible = ref(false);
let timer;
const showToast = () => {
visible.value = true;
clearTimeout(timer);
timer = setTimeout(() => {
visible.value = false;
}, 2000);
}
return {
visible,
showToast
}
}
}
復制代碼
效果展示:

可以看到,我們使用 teleport 組件,通過 to 屬性,指定該組件渲染的位置與 <div id="app"></div> 同級,也就是在 body 下,但是 teleport 的狀態(tài) visible 又是完全由內(nèi)部 Vue 組件控制
與 Vue components 一起使用 —— modal
如果 <teleport> 包含 Vue 組件,則它仍將是 <teleport> 父組件的邏輯子組件
接下來我們以一個 modal 組件為例
<div id="app"></div>
<div id="teleport-target"></div>
+ <div id="modal-container"></div>
<script type="module" src="/src/main.js"></script>
復制代碼
<teleport to="#modal-container">
<!-- use the modal component, pass in the prop -->
<modal :show="showModal" @close="showModal = false">
<template #header>
<h3>custom header</h3>
</template>
</modal>
</teleport>
復制代碼
JS 核心代碼如下:
import { ref } from 'vue';
import Modal from './Modal.vue';
export default {
components: {
Modal
},
setup() {
// modal 的封裝
const showModal = ref(false);
return {
showModal
}
}
}
復制代碼
在這種情況下,即使在不同的地方渲染 Modal,它仍將是當前組件(調(diào)用 Modal 的組件)的子級,并將從中接收 show prop
這也意味著來自父組件的注入按預期工作,并且子組件將嵌套在 Vue Devtools 中的父組件之下,而不是放在實際內(nèi)容移動到的位置
看實際效果以及在 Vue Devtool 中

總結(jié)
本文主要介紹了 Vue 3 的新特性——Teleport,從為什么要使用 Teleport,以及通過兩個小 demo,演示它的基礎使用,希望能夠?qū)δ阌袔椭?a target="_blank">https://www.bilibili.com/video/BV1B54y1m7LC