Vue 3에서 기본으로 제공되는 기능 중 하나인
텔레포트(Teleport)를 Vue2에서 사용하려고 합니다. 어떻게 하면 가능할 지 아래에서 알아봅니다.
# Vue2 텔레포트 기능, portal-vue
vue2에서는 <Teleport> 기능을 사용할 수 없기 때문에 다른 방법이 필요합니다... 이에 여러 방법을 생각해볼 수 있으나 가장 간편한 방법은 바로 node package인
portal-vue를 설치해 사용하는 방법입니다.
(사실 teleport와 비슷한 여러 패키지가 존재하지만 해당 패키지 가장 많이 사용되고 있습니다.) 아래에서는
portal-vue가 무엇이고 텔레포트를 하는 이유... 그리고 그 사용 방법에 대하여 간략하게 알아보겠습니다.
! Vue에서 Teleport 기능은?
텔레포트는 Vue3에서 제공되는 기능으로
원하는 곳에 특정 컴포넌트 또는 노드를 추가할 수 있는 기능입니다. 여기서 노드를 추가한다는 의미를
컴포넌트에서 선언된 <template> 밖에도 추가가 가능하다는 점입니다. 예를들어 최상위 컴포넌트나 레이아웃, 페이지 아니면 반대로 하위의 자식 컴포넌트에도 가능합니다. 예를들어 아래와 같이 가능합니다.
<body>
<AComponent>
<div>
<MyComponent />
</div>
</body>
위 코드처럼 MyComponent 내부에 위치한 AComponent를 body 아래로 이동시켰습니다.
마치 텔레포트를 사용한 것처럼 말이죠. 그래서 텔레포트 기능이라고 합니다. 엘리먼트를 원하는 곳으로 보내기 위해 document.appendChild()를 사용한 것과 비슷합니다.
이 기능을 사용하려면 Vue3 이상에서 사용하거나 아니면 portal-vue 처럼 해당 기능을 제공하는 노드 패키지가 필요합니다. 이를 사용하기 위해 설치 및 설정 방법을 알아봅니다.
! portal-vue 설치 및 설정하기
우선 해당 패키지는 아래의 링크에서 확인 가능합니다.
https://www.npmjs.com/package/portal-vue설치를 위해서 아래와 같이 명령어를 입력합니다.
> npm install portal-vue
설치가 끝났다면 설정을 위해서 해당 패키지를 vue에 추가하도록 합니다.
import PortalVue from 'portal-vue'
Vue.use(PortalVue)
만약 nuxtjs를 사용하는 중이라면 nuxt.config.js의 modules에 아래와 같이 추가해야 합니다.
modules: [
'portal-vue/nuxt',
...
],
이제 설치 및 설정은 간단하게 끝났습니다. 그럼 예제한 예제를 만들고 어떻게 사용하였는지 확인해봅니다.
@ 예제) 특정 컴포넌트나 엘리먼트에 portal 사용하기portal-vue를 사용하려면 보낼 코드와 받는 코드를 둘 다 작성해야 합니다. 먼저 받을 위치를 정한다음 그 곳에 아래와 같이 <portal-target name="targetName">을 사용합니다. 만약 Page.vue 파일의 template으로 보낼 경우의 예제입니다.
Page.vue<template>
<div>
<portal-target name="APage">
</portal-target>
</div>
</template>
받기 위한 name 속성은 키 값이라고 보면됩니다. 여기서는 APage를 사용하였습니다.
이제 Page.vue의 div 아래에 원하는 경우 언제든지 컴포넌트를 보낼 수 있게되었습니다. 물론 태그 요소도 가능합니다. 보내는 쪽 코드도 마져 작성해보겠습니다.
AComponent.vue<template>
<div>
<portal to="APage">
<p>Hello!</p>
</portal>
</div>
</template>
보내는 쪽은 <p>Hello!</p> 태그 요소를 전달하였습니다. 받는 쪽 코드를 여러 개 설정해두면 언제든 원하는 위치로 텔레포트 하는 것이 가능하게 될 것입니다.
여기까지 텔레포트 기능 구현을 알아봤습니다. 한 번 더 얘기하면 Vue3인 경우 자체 지원하는 <Teleport>를 사용할 수 있습니다. Vue2 이하에서의 사용 방법입니다.
! 왜 Teleport를 사용하고 언제 필요할까?
텔레포트를 사용하면 무엇이 좋을까요? 크게 두 가지를 구현 가능하다고 얘기할 수 있습니다.
- 레이어의 위계(하이라이키)를 지키기 위해 스타일 이슈가 발생하는 것을 미연에 방지
- 비즈니스 로직과 템플릿을 원하는 곳에서 구현하고 분리가 가능
더 있겠지만 크게 두 가지를 위해서 사용할 수 있겠죠. 1번의 경우 모달 등의 레이어 팝업을 사용할 때 태그 위계에 따라 브라우저 및 환경에 따라 달리 보일 수 있습니다. 이런 이유로 body 아래에 추가하는 등의 방법으로 사용할 수 있겠습니다.
다음으로 2번 째는 정해진 비즈니스 로직을 지키기 위해서도 될 수 있습니다. 즉 템플릿의 View와 데이터에 해당하는 Model을 하나의 컴포넌트에서 사용하더라도 컴포넌트 하위 로직인 View에 대한 종속성을 벗어날 수 있습니다. 동일한 데이터 플로우를 지키기 위해서 사용이 가능하겠습니다.