Modal ve Tooltip’leri Nerede Render Edelim?
Vue’da component’ler genellikle kendi kapsayıcıları (parent element) içinde render edilir. Ancak bazı durumlarda -- özellikle modal, tooltip veya dropdown gibi UI öğelerinde -- bu davranış sorun çıkarır. Çünkü bu bileşenler genellikle sayfa hiyerarşisinden bağımsız, z-index veya overflow gibi CSS özelliklerinden etkilenmeden görüntülenmelidir.
Vue 3’ün sihirli özelliği Teleport, tam da bu noktada devreye giriyor.
Teleport sayesinde bir bileşeni, kodda bir yerde tanımlayıp DOM’un bambaşka bir yerine render edebilirsin. Kısaca: “Ben burada yazıyorum ama orada görün!” demektir.
Teleport Nedir?
<teleport> özel bir Vue bileşenidir. to adlı bir prop alır ve bu prop, bileşenin nereye taşınacağını belirtir.<template>
<teleport to="body">
<div class="modal">Merhaba Dünya 🌍</div>
</teleport>
</template>
Bu örnekte modal, DOM’un body etiketine taşınır. Böylece CSS açısından üst katmanlarda tanımlı overflow: hidden, position: relative gibi sınırlamalar bu bileşeni etkilemez.
Kısaca: Teleport, Vue’nun içinde bir “portaldır.” Görünürlük aynı kalır ama DOM konumu değişir.
Neden Gerek Duyarız?
Normalde parent bileşen içindeki bir modal şu sorunları yaşar:overflow: hiddenyüzünden görünmez olur.z-indexhiyerarşisine takılır, başka elementlerin arkasında kalır.position: relativekonteynerleri yüzünden beklenmedik hizalama sorunları çıkar.
body seviyesine taşıyarak bu kısıtlamaları aşabiliriz. Bu, özellikle karmaşık layout’larda “tooltip görünmüyor” türü hataları ortadan kaldırır.Basit Bir Modal Örneği
<template>
<button @click="show = true">Modal Aç</button>
<teleport to="body">
<div v-if="show" class="modal-backdrop" @click="show = false">
<div class="modal" @click.stop>
<h2>Teleport Modal</h2>
<p>Bu modal, body’ye taşındı!</p>
</div>
</div>
</teleport>
</template>
<script setup>
import { ref } from 'vue'
const show = ref(false)
</script>
<style>
.modal-backdrop {
position: fixed;
top: 0; left: 0;
width: 100vw; height: 100vh;
background: rgba(0,0,0,0.5);
}
.modal {
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
background: white;
padding: 2rem;
border-radius: 8px;
}
</style>
Bu örnekte modal kodu bileşenin içinde yazılmış olsa da, Vue onu DOM’un body kısmına taşıyacaktır. Yani bileşen mantıksal olarak parent içinde kalır, ama görsel olarak üst katmanda görünür.to Prop’u Daha Detaylı
to prop’u bir CSS seçici veya DOM element referansı olabilir:<teleport to="#portal-target">
<MyTooltip />
</teleport>
veyaconst el = document.querySelector('#modals')
<teleport :to="el">
<MyModal />
</teleport>
Eğer hedef element mevcut değilse Vue otomatik olarak uyarı verir, bu yüzden render öncesinde hedefin DOM’da olduğundan emin ol.Teleport İçinde Reaktivite Devam Eder
Teleport bileşenler, taşındıkları yerde de reactive olmaya devam ederler. Çünkü Teleport yalnızca DOM seviyesinde bir taşıma yapar -- Vue reaktivite sistemi değişmez.<teleport to="body">
<p>{{ message }}</p>
</teleport>
message reactive bir değişken olarak aynı component’te güncellendiğinde Teleport içeriği de otomatik güncellenir.Yani Teleport bir “render portalı”, ama “reactive portal” değildir -- reactive bağlar yerinde kalır.
İleri Seviye Kullanımlar
1. Birden Fazla Teleport
Aynı bileşen içinde birden fazla Teleport kullanabilirsin. Örneğin hem tooltip’leri hem modalları farklı DOM alanlarına taşımak için:<teleport to="#tooltips">
<MyTooltip />
</teleport>
<teleport to="#modals">
<MyModal />
</teleport>
Bu, büyük ölçekli UI sistemlerinde UI Layer Separation sağlar.2. Teleport İçinde Transition
Animasyonlu modal geçişleri için Teleport’uTransition bileşeniyle birlikte kullanabilirsin:<teleport to="body">
<transition name="fade">
<Modal v-if="open" />
</transition>
</teleport>
Transition, Teleport içeriğini DOM’dan bağımsız olarak yönetir, animasyonlar sorunsuz çalışır.3. SSR (Server-Side Rendering) Desteği
Teleport, SSR’de de desteklenir. Vue, Teleport içeriğini render ederken hedef DOM yerine bir placeholder üretir ve hydration sırasında uygun yere taşır.Yaygın Hatalar
- Teleport hedefi (
to) DOM’da yoksa, içerik görünmez. - Parent bileşen
overflow:hidden’sa, Teleport’suz modal görünmez. z-indexçakışmalarını çözmek için Teleport edilen içeriğe ayrı katman stilleri ver.- CSS scoping (
scopedstiller) Teleport edilen içerikte geçerli değildir --:deep()kullanmak gerekebilir.
Sonuç
Teleport, Vue’nun modern UI bileşenlerini doğru yerde gösterebilmen için sunduğu en pratik araçlardan biridir. Modal’lar, tooltip’ler, context menüler ve dropdown’lar artık overflow sorunlarına takılmadan çalışabilir.Kısaca:
teleport to="body"→ DOM’un üst katmanına taşı- Reaktivite korunur, yalnızca render konumu değişir
- Karmaşık arayüzlerde düzeni ve erişilebilirliği artırır