vue 프로젝트를 하다보면 dialog 혹은 모달 이라고도 많이 부르는데 어쨌든 그걸 사용할 일이 꽤 많다
직접 구현할수도 있겠지만 나는 vuetify의 v-dialog를 사용해서 구현했다
근데 dialog를 그냥 한 컴포넌트 안에서 사용하면 v-model 연결하기도 편하고 dialog를 다루기에 편하긴 하지만
한 컴포넌트 안에 넣다보면 코드도 길어지고,
만약 같은 dialog를 사용할 일이 많다면 컴포넌트로 분리하는게 재사용성도 좋고 가독성, 유지보수 면에서도 좋다
그래서 오늘은 vuetify에서 사용하는 v-dialog를 컴포넌트로 분리하는 법에대해 알아보겠다
컴포넌트를 분리함에 있어 props, emit은 거의 필수적이기 때문에 같이 공부해 보겠다
참고로 나는
여기를 정말 많이 참고했다
(근데vue3 Composition api로 코드를 작성하려니 잘 안되는 부분이 있어서 내 방법으로 조금 수정했다)
(내가 생각한 흐름대로 설명을 할거라 글이 길어지고 멍청해 보일수도 있다 주의하길 ㅋㅋㅋ)
먼저 프로젝트를 생성해준다
vuetify를 사용할거기 때문에 npm create vuetify 로 프로젝트를 생성한다
적당히 삭제할거 삭제하고 정리를 해준 뒤
<template>
<div class="wrap">
<div class="text">
{{title}}
<v-btn>제목 바꾸기 다이어로그 열기</v-btn>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const title = ref('안녕 나는 제목이야')
</script>
<style lang="scss" scoped>
@import '../styles/practice.scss';
</style>
이런식으로 HelloWorld.vue를 일단 작성했다
이런식의 화면이 나올거고
오늘 해볼거는 저 버튼을 누르면 다이어로그가 열리고
그 다이어로그 안에 있는 제목 바꾸기 버튼을 누르면 제목이 바뀌는 것을 해보겠다
일단 다이어로그가 버튼을 눌렀을때 잘 열리고 닫히게 해야한다
여기서 정말 많이 헤맸는데
헤매는 과정을 설명하려했으나 너무 복잡해져서 일단 결과물을 보여주고 설명하겠다
(자세한 설명은 위에 내가 참고했다던 블로그를 보시길...)
이렇게 작성하면 일단 버튼을 누르면 다이어로그가 잘 열리고
바깥 공간을 클릭하면 다이어로그가 잘 닫히는 것을 확인할 수 있다
여기서 @toggle="openDialog = $event" 이 부분이 있는데
$event 이 부분은 아직 정확하게 이해하지는 못해서 더 공부해봐야겠다
openDialog를 프롭스로 내려주고
다이어로그 컴포넌트에서는 computed를 통해 openDialog가 바뀔때
바뀐 값을 다시 emit으로 helloworld 컴포넌트에 넘겨준다
이런식으로 작성하지 않고 다른 방법들을 써봤는데
다이어로그가 한번 열리는것까지는 잘 되는데 닫거나,
한번 닫고 다시 여는 과정에서 문제가 생긴다
그 이유는 위에 참고 블로그에 잘 나와있으니 궁금하다면 가서 확인하시길
쨌든 저렇게 작성하면 일단 dialog가 잘 열리고 닫힌다
이제 제목을 바꾸는걸 해보겠다
이렇게 작성해 줬고 화면은
이런식이다
css를 안손대서 좀 구리긴 하지만
제목을 입력하고 바꾸기 버튼을 누르면 제목이 잘 바뀌는것을 확인할 수 있다
원래 props, emit도 자세히 설명하려 했지만 쬐끔 귀찬기도 하고
저 코드를 보면 대충 이해가 잘 될거라 생각한다
오늘은 vue3에서 vuetify의 v-dialog를 컴포넌트로 분리하는 방법에 대해 알아봤다
이게 검색해도 자료가 많이 없어서 고생 쪼끔 했는데
혹시나 나와같은 상황에 있다면 부디 내 글이 도움이 됐길 바란다!
참고로 다른 방법이 있는데 바로 스토어에 다이어로그의 boolean값을 저장해서 연결해서 쓰는 방법이다
이 방법은 정말 간편하고 좋은데 dialog 열고 닫는거를 스토어에 저장하기 쫌 찝찝한 감이 있다(근데 솔직히 진짜 개편하긴함)
하지만 여러곳에서 똑같이 사용하는 다이어로그라면 스토어를 쓰는 방법도 깔끔하고 좋은것 같다
각각 장단점이 있으니 상황에 맞게 잘쓰시길...
혹시나 스토어 활용법이 궁금하다면 댓글이든 뭐든 연락을 주시길..