본문 바로가기

Vue.js

[Udemy Vue 완벽가이드 Section9] 121. 텔레포트(Teleport)를 활용하여 요소 이동시키기

error dialog에 무슨 문제가 있을까?

겉보기에는 문제가 없어 보인다.

 

하지만 검사를 해보면 HTML 마크업에 문제가 있는 것을 볼 수 있다.

dialog 태그가 div태그 아래에 h2, input, button태그들과 같이 중첩되어 있다.

 

 

물론, ManageGoals.vue 컴포넌트 템플릿에서 이곳에 추가했기 때문이다.

하지만, semantic관점과 HTML 관점에서 dialog요소를 이 위치에 놓는 것은 dialog가 전체 페이지에 오버레이된다는 문제가 있다. 

이 dialog를 여기에 놓는 것은 HTML 측면에서 이상적이지 않다.

작동은 하지만, 접근성을 생각해보면 이상하다. 또한 스타일링 문제가 발생할 수 있다.

코드 깊은 곳에 위치하지않고, HTML 트리의 루트에 삽입하는게 이상적이다.

semantic 측면의 이유 때문이며, 부분적으로는 접근성을 위한 이유 때문.

 

# teleport

dialog의 위치는 Vue에서 제공하는 텔레포트(Teleport) 기능으로 쉽게 옮길 수 있다.

텔레포트(teleport)는 component, keep-alive처럼 Vue에서 제공하는 내장 컴포넌트이다.

다른 곳으로 텔레포트하고 싶은 부분, 즉 다른 곳에 렌더링하고싶은 부분을 텔레포트로 감싸면된다.

이 경우에는 error-alert를 감싸주면 된다.

<!--ManageGoals.vue-->
<teleport to="body">
 <error-alert v-if="inputIsInvalid">
   <h2>Input is invalid!</h2>
   <p>Please enter at least a few characters..</p>
   <button @click="confirmError">Okay</button>
 </error-alert>
</teleport>

 

## teleport 작성방법

teleport는 to라는 한 가지 속성을 필요로한다. 여기에 CSS 선택자를 넣어서 전체 페이지에서 HTML 요소를 선택한다.

논리상 error-alert는 여전히 ManageGoals.vue 컴포넌트에 속하며, 이 컴포넌트에서 메서드와 상호작용도 할 수 있지만, DOM구조 내 다른 곳에서 렌더링된다.

 

예를 들어, body 태그를 참조하여 body요소를 선택할 수 있다.

또는 id선택자를 선택해, <teleoport to="#app"> 이런 식으로 요소를 참조할 수도 있다.

일반 CSS선택자를 선택할 수도 있다.

to="body" 이 말은, 이 컴포넌트의 내용을 렌더링하고 DOM에 추가되어야하는 실제 HTML 마크업을 body요소에서 직접 렌더링하라는 뜻. 이전처럼 HTML 구조에 깊게 중첩되지 않도록.

 

저장하고 새로고침해보자.

dialog를 열어보면 이전과 화면은 같다. 하지만 개발자도구를 보면 dialog가 body 섹션 아래에 있다. 더는 div와 다른 요소에 깊게 중첩되어있지 않다.

semantic 측면에서 이 방식이 더 낫다.

 

 

작은 최적화방식이고, 상관없을 수도 있다. 원하지 않는다면 쓰지 않아도 된다.

하지만 사용하기 쉽고, 전체 HTML 구조에 도움이 될 수 있으며, 단순히 보기 좋고 동작이 잘 되는 애플리케이션을 만드는 것 이상으로 semantic 측면에서 올바른 HTML 구조를 만들 수 있게 해준다. teleport가 이를 가능하게 해준다.

 

 

** 출처: 모든 내용은 Udemy Vue-완벽가이드 강의를 기반으로 작성하였습니다.