先前在 Day19 Vue 插槽 Slots (上) 的內容中,有提到 slot 可以將父元件的模板片段內容渲染在子元件中的指定位置,但是其燈箱(lightbox)的背景無法遮蔽住整個網頁的畫面,因此透過使用 Teleport 便可以解決此問題。
Teleport 是 Vue 提供的一個內置元件,可以將元件模板中的 DOM 內容傳送到指定的位置渲染,此外Teleport 只會改變渲染的 DOM 結構,並不會影響元件間的邏輯關係(父子關係),因此傳入的 props 和觸發的事件也會正常運作。
將要移動的元素寫在模板中的<teleport>
標籤裡,並且使用 to 屬性來指定傳送的目的地,其中 to 的值可以是 CSS 選擇器字符串或 DOM 元素對象。
以下是官方文件的範例
Vue 會把<teleport>
標籤裡的模板片段傳送到<body>
標籤渲染。
<button @click="open = true">Open Modal</button>
<Teleport to="body">
<div v-if="open" class="modal">
<p>Hello from the modal!</p>
<button @click="open = false">Close</button>
</div>
</Teleport>
透過使用 disabled 屬性可以控制元素是否會被移動到 to 指定的位置渲染。
<!-- 當 showInPortal 為 false 時,內容不會渲染在body -->
<Teleport to="body" :disabled="!showInPortal">
<div class="modal">
<p>這個內容的位置會根據 disabled 屬性改變</p>
</div>
</Teleport>
在模板中使用多個<teleport>
標籤可以將其內容掛載在同一個目標元素上,會依照定義的順序來進行渲染,因此後掛載的將排在目標元素下更後面的位置。
以下是官方文件的範例
<Teleport to="#modals">
<div>A</div>
</Teleport>
<Teleport to="#modals">
<div>B</div>
</Teleport>
等同於
<div id="modals">
<div>A</div>
<div>B</div>
</div>
https://zh-hk.vuejs.org/guide/built-ins/teleport.html
https://book.vue.tw/CH2/2-4-slots.html
https://ithelp.ithome.com.tw/m/articles/10274013