일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- next.js
- HTML
- 클라우드
- 파이썬
- 블록체인
- 백준
- 리액트
- 자바스크립트
- BFS
- 컴퓨터공학
- 타입스크립트
- react
- AWS
- 이더리움
- JavaScript
- 이슈
- 백엔드
- es6
- 프론트엔드
- 쿠버네티스
- 알고리즘
- 솔리디티
- 웹
- VUE
- docker
- k8s
- CSS
- kubernetes
- 가상화
- TypeScript
- Today
- Total
즐겁게, 코드
Vue 3에서 페이지 전환 애니메이션 추가하기 본문
리액트와 비교했을 때 뷰의 장점 중 하나는 유용한 빌트인 컴포넌트를 제공한다는 점이라 생각한다.
이 중 <Transition>
컴포넌트는 정말 유용하게 사용하고 있는 중인데, 페이지 전환 시에도 트랜지션 효과를 줄 수 있다고 한다.
<template>
<div>
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
<router-link to="/contact">Contact</router-link>
</div>
<router-view />
</template>
nuxt가 아닌 vue-router로 라우터를 구성하면 위와 같이 router-view
컴포넌트를 사용한다.
<template>
<div>
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
<router-link to="/contact">Contact</router-link>
</div>
<Transition name="트랜지션 이름">
<router-view />
</Transition>
</template>
그리고 <Transition>
으로 <router-view>
를 감싸면 애니메이션이 잘 적용된 것처럼 보이나, 콘솔에 경고가 출력된다.
<template>
<div>
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
<router-link to="/contact">Contact</router-link>
</div>
<router-view v-slot="{ Component }">
<component :is="Component" />
</router-view>
</template>
대신 router-view
는 "Component" 라는 named slot을 expose하는데, expose된 Component 슬롯을 동적으로 렌더한다.
(※ 여기서 Component 는 현재 경로에서 렌더링되어야 하는 컴포넌트다.)
<template>
<div>
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
<router-link to="/contact">Contact</router-link>
</div>
<router-view v-slot="{ Component }">
<Transition name="route" mode="out-in">
<component :is="Component" />
</Transition>
</router-view>
</template>
이제 동적으로 렌더한 <component />
컴포넌트에 <Transition>
컴포넌트를 감싸면 경고가 사라지고, 멋진 라우팅 네비게이션이 적용된 것을 확인할 수 있다.
번외. 그런데 왜 경고가 출력됐던 것일까?
먼저 GPT의 답변은 <router-view>
는 functional component 이며 <Transition>
은 stateful component 이므로 둘의 동작이 달라 부작용이 생길 수 있다는 내용이다.
vue-router의 <router-view>
는 다음과 같이 구현되어 있다.
그리고 Vue의 <Transition>
유틸 컴포넌트는 다음과 같이 구현되어 있다.
BaseTransition을 살펴보면 setup API를 활용해 stateful하게 동작하고 있는데, <router-view>
은 setup 없이 가상 DOM을 구성하는데 사용하는 VNode만을 리턴하고 있다.
즉 <router-view>
는 functional component고 <Transition>
은 stateful component를 children으로 받기를 기대하지만, Composition API의 도움으로 functional과 stateful이 함께 사용될 수 있는 것이다.
(= 즉 원래대로면 Error 가 되었어야 하는 부분을 Warning 으로 누그러뜨릴 수 있었던 것 같다.)
추가로 알아볼 키워드
- h (hyperscript) 함수
- Composition API
- VNode
'🎨 프론트엔드 > Vue.js' 카테고리의 다른 글
vee-validate에 타입스크립트 적용하기 (@vee-validate/yup) (0) | 2024.12.19 |
---|---|
[Vue] inject-provide 패턴 조금 더 잘 써보기 (0) | 2024.11.19 |
Vuex의 namespaced module 활용하기 (0) | 2022.04.04 |
v-show와 v-if 지시자의 차이 (0) | 2021.08.18 |
Vue 컴포넌트에서 name 속성을 명시하는 이유 (0) | 2021.05.24 |