티스토리 뷰
지난 글에서는 페이지 이동할 때 transition을 적용했다면 이번 글에서는 모달창이 나올 때의 transition을 적용해보겠다. 모달창의 경우에는 <teleport>
태그를 활용하여 DOM상에서 등록되는 위치를 분리해준다.
// index.html
<body>
<div id="app"></div>
<div id="desktop-modal"></div>
</body>
// TeleportModal.vue - template
<teleport to="#desktop-modal">
<div class="modal">
<transition name="slide-up" appear>
<div class="modal-content" ref="modalRef">
<div>
<div>
<h1>This is Modal</h1>
<button @click="modalStore.closeModal()">Close</button>
</div>
</div>
</div>
</transition>
</div>
</teleport>
모달창이 등장하는 transition은 아래에서 위로 올라오는 slide-up을 사용할 것이다. 여기서 버그인지는 모르겠으나 slide-up-leave는 작동하지 않는 문제가 발생했다. 추정하기로는 <TeleportModal v-if="isModalShow" />
처럼 v-if
로 조건부 렌더링을 걸어버리면 isModalShow
가 false
가 되어버리자마자 DOM에서 사라지게 되어 transition-time
을 무시해버리는 것 같다. 이 문제를 해결하기 위해서 modalStore.closeModal()
이 호출될 때는 modal-content
에hide
라는 별도의 css transform을 정의해서 사라지게 만들었다.
// TeleportModal - style
.modal {
position: fixed;
inset: 0px;
z-index: 10;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(0, 0, 0, 0.5);
}
.modal .modal-content {
width: 50vh;
height: 300px;
background-color: white;
display: flex;
align-items: center;
justify-content: center;
}
/* 위에서 올라오는 동작 ON */
.slide-up-enter-from {
transform: translateY(100%);
}
.slide-up-enter-active {
transition: transform 0.2s ease-in-out;
}
.modal-content.hide {
transform: translateY(100%);
transition: transform 0.2s ease-in-out;
}
// stores/modal.js
import { defineStore } from "pinia";
export const useModalStore = defineStore("modal", {
state: () => {
return {
modal: false
};
},
actions: {
openModal() {
this.modal = true;
},
closeModal() {
const modalEl = document.querySelector(
"#desktop-modal .modal .modal-content"
);
if (modalEl) {
modalEl.classList.add("hide");
const toId = setTimeout(() => {
this.modal = false;
clearTimeout(toId);
}, 200);
}
}
}
});
다음 글에서는 현재 떠 있는 모달창이 닫히는 기능을 구현해보도록 하겠다.
'Dev' 카테고리의 다른 글
vue에서 router내 DOM을 querySelector로 찾지 못하는 문제 (0) | 2023.04.04 |
---|---|
vue3 modal 모달 열고 닫기 (0) | 2023.03.09 |
vue3 route transition(라우트 트랜지션) (0) | 2023.03.09 |
vue-chart-3에서 비동기 통신 이후 데이터 그리기 (0) | 2023.03.09 |
vue 에서 스크롤 위치 저장 (0) | 2023.03.09 |