μ°Έκ³
https://vuejs.org/guide/essentials/template-syntax.html
https://vueschool.io/lessons/vue-3-teleport?friend=vuejs
https://www.youtube.com/watch?v=Mi2TfYu0XuM
π‘ μ§λ Modal μ ꡬνν λλ μ κΉ Teleport μ λν΄ μ€λͺ μ νμ§λ§, Vue μμ Advanced Topic μ΄κΈ° λλ¬Έμ μμ μ ν¨κ» λ μ΄ν΄λ³΄κ³ μ νλ€.
μ΄λ¦μμ λκ»΄μ§λ ν λ ν¬νΈλ μ΄λλ‘ κ° μ΄λν μ μλ κ²μ λ§νλ€.
//App.vue
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Vue 3" />
<div id="purple-box" style="bordeR: purple 2px solid; min-height: 50px"></div>
</template>
App.vue λ μμ μ»΄ν¬λνΈ HelloWrold.vue λ₯Ό import νλ€.
//HelloWorld.vue
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<button @click="showMessage = !showMessage">Toggle Message</button>
<button @click="showModal = true">Show Modal</button>
<Teleport to="#purple-box">
<p v-if="showMessage">Hello from HelloWorld</p>
</Teleport>
</div>
</template>
HelloWorld.vue μ»΄ν¬λνΈλ λΆλͺ¨ μ»΄ν¬λνΈμμ idκ° purple-boxμΈ div νκ·Έμ λ§κ² Teleport νκ·Έλ‘ toμμ±μ #purple-box λ₯Ό κ°λ¦¬ν¨λ€.
//public > index.html
...
<div id="app"></div>
<!-- built files will be auto injected -->
<div
id="purple-box"
style="border: purple 2px solid; min-height: 50px"
></div>
...
μ΄ λ¬Έμ λ₯Ό ν΄κ²°νκΈ° μν΄ public ν΄λμ index.html μμ id κ° app μΈ div νκ·Έ μλμ App.vue μ»΄ν¬λνΈμμ idκ° purple-boxμΈ divνκ·Έλ₯Ό μ¬κΈ°λ‘ μ΄λμν€λ κ²λ νλμ λ°©λ²μ΄λ€. μ΄ λ°©λ²μ Vue μ±μ΄ μμνκΈ° μ μ #purple-box κ° λ¨Όμ μμ±λμ΄ μ€λ₯λ₯Ό λ°©μ§ν μ μλ€.
νμ§λ§, Vueμ κ°λ ₯ν νΉμ±μ νμ©νλ €λ©΄ Vue μ»΄ν¬λνΈ λ΄μμ μ리먼νΈλ₯Ό μ‘°μνλ λ°©λ²μ μ¬μ©νλ κ²μ΄ λ μ’μ μ μλ€.(μ. mounted ν )
//App.vue
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Vue 3" />
</div>
<Teleport to="#purple-box">
<button>DO NOT CLICK</button>
</Teleport>
</template>
App.vue μ»΄ν¬λνΈλ₯Ό μμ νκ³ , Index.html μ div νκ·Έ μ½λλ₯Ό μΆκ°νλ©΄,
App.vue μ»΄ν¬λνΈμλ idκ° appμΈ div νκ·Έ μλμ img μ HelloWorld μ»΄ν¬λνΈκ° μμ μμλ‘ λ€μ΄κ°κ³ , Teleport νκ·Έλμμ μμκ° μλλΌ λ°μΌλ‘ λΉ μ Έμλ€.
μ€νμΌ μμλ₯Ό μν΄ λ°μΌλ‘ λΉΌμ μμΉμν€λ κ²½μ°κ° λ°λ‘ μ§λ μκ°μ ꡬνν΄λ³΄μλ λͺ¨λ¬ UI μ΄λ€.
μ ν리μΌμ΄μ DOM κ³μΈ΅ ꡬ쑰μ κΉκ² μ€μ²©λλ€λ κ²μ μλ―ΈνκΈ° λλ¬Έμ Teleport λ₯Ό μ΄μ©νλ€λ©΄ λ λλ§λ DOM κ΅¬μ‘°λ§ λ³κ²½νλ©° κ΅¬μ± μμμ λ Όλ¦¬μ κ³μΈ΅ ꡬ쑰μλ μν₯μ μ£Όμ§μλλ€. μ¦, Teleport κ΅¬μ± μμκ° ν¬ν¨λ κ²½μ° ν΄λΉ κ΅¬μ± μμλ₯Ό ν¬ν¨νλ μμ κ΅¬μ± μμμ λ Όλ¦¬μ νμ νλͺ©μΌλ‘ μ μ§λλ€.
teleport νκ·Έλ₯Ό μ¬μ©ν λλ to μμ±μ μ¬μ©ν΄μΌ νλ€.
to μμ±μ κ°μΌλ‘λ index.html νμΌμμ μμ±ν div νκ·Έμ id κ°μΌλ‘ μ΄λν λμμ μ§μ νλ€. DOM μμμ μ
λ ν° λ¬Έμμ΄μ΄λ μ€μ DOM μμ μμ²΄κ° λ€μ΄κ° μλ μλ€.
true μ false μ booleanκ°μΌλ‘ νμ±νμν€κ±°λ λΉνμ±νμν¬ μ μλ μμ±μ΄λ€.
Vue3 μ Teleport μ»΄ν¬λνΈμμ μ§μ μ μΌλ‘ μ 곡νμ§λ μμ§λ§, νΉμ 쑰건μ λ°λΌ μ€μ ν μ μλ€.
<template>
<button @click="show = true">Show modal</button>
<Teleport to="body" :disabled="true">
<Modal :show="show" @close="show = false">
<template #header>
<h3>custom header</h3>
</template>
</Modal>
</Teleport>
</template>
True λ‘ μ€μ νκ² λλ©΄ id κ° appμΈ div νκ·Έμ μμμΌλ‘ modalμ΄ λνλλ€.
<template>
<button @click="show = true">Show modal</button>
<Teleport to="body" :disabled="false">
<Modal :show="show" @close="show = false">
<template #header>
<h3>custom header</h3>
</template>
</Modal>
</Teleport>
</template>
False λ‘ μ€μ νκ² λλ©΄ id κ° appμΈ div νκ·Έμ μμμΌλ‘ modalμ΄ λνλλ€.
trueμΌ κ²½μ° | falseμΌ κ²½μ° |
---|---|
![]() | ![]() |
id κ° appμΈ div νκ·Έμ μμμ΄κ±°λ μμ λ€λ₯Έ div λ‘ λνλ΄λ λ€λ₯Έ μ μ΄ μκΈ΄ νμ§λ§, Teleportλ₯Ό μ΄μ©νμ¬ μκ°μ΄λμ²λΌ μμ κ΅¬μ± μμμ μ£Όμ μ΄ μμλλ‘ μλνκ³ , νμ κ΅¬μ± μμκ° μ€μ μ½ν μΈ κ° μ΄λλ μμΉμ λ°°μΉλκ² ν μ μλ€λ μ μ΄λ€.
vue κ° μλ react λ₯Ό μ΄μ©ν jsλ ts μμλ λͺ¨λ¬μ ꡬννκΈ° μν΄μλ νμ μ μΌ λ°κΉ₯ div νκ·Έμμ μΆκ°μμΌ μλμΌλ‘ κ΄λ¦¬ν΄μΌνλ μ μ΄ μμμ§λ§, teleport λ₯Ό μ¬μ©ν¨μ λ°λΌ μ΄λμλ μ΄λμν¬ μ μκΈ° λλ¬Έμ μ μμ μΌλ‘ κ΄λ¦¬ν μ μκ³ , λͺ¨λ¬μ λ§ν¬μ μ΄ μ»΄ν¬λνΈ μ체μμ λΆλ¦¬λ μ μμ΄ λͺ¨λ¬ μ»΄ν¬λνΈλ λͺ¨λ¬μ λμκ³Ό λ‘μ§μλ§ μ§μ€ν μ μλ€. λν , λΌμ΄νμ¬μ΄ν΄μ λ μΈλ°νκ² μ μ΄ν μ μλ μ΄μ μ΄ μμ΄ vue μ μ€μνκ³ μμ£Ό νΈλ¦¬ν κΈ°λ₯μ΄λΌκ³ λκ»΄μ§λ€.