Vue.js 양방향 데이터 바인딩 활용 : 모달(레이어팝업) 컴포넌트 만들기를 통하여 알아보기(.sync)
모달(레이어 팝업)이 뭐 별거 있겠냐고 생각될 수 있지만, vue.js에서 자유롭게 모달을 열고 닫는 로직을 구현하는게 생각보다는 단순하지 않다. 그 해법이 양방향 데이터 바인딩이다. 그리고 양방향 데이터 바인딩은 조심스럽게 사용해야하고 잘 이해하고 있어야 하는데, 모달을 제작하는 과정에서 그것을 잘 배울 수 있다. 내가 사용하는 방법을 정리해보고자 한다.
상황 : parent 컴포넌트가 있다. parent는 my-modal이라는 자식 컴포넌트를 가지고 있다. my-modal 컴포넌트는 모달이다. parent 와 모달의 관계는 부모자식 관계이기 때문에 visible이라는 props를 이용하여 모달을 띄우고 닫을 수 있을거라고 생각할 수 있다.
일단 심플한 모달을 하나 만들어보자.
my-modal.vue
visible값을 props로 모달에게 전달하여 모달을 띄우거나 닫을 수 있다. 이제 모달을 띄우는 parent 컴포넌트를 만들어보자.
parent.vue
자 문제없이 모달이 잘 열린다. 이제 모달 헤더에 닫기 버튼을 넣고자 한다. 그런데 visible은 props로 전달되므로 자식 내부에서 전달 받은 props를 변경하는건 문제가 있다. 모달전용 내부 변수를 만들어서 모달을 닫았다고 하더라도 부모가 현재 모달의 상태를 알 수 없다는 문제가 남는다.
문제1 : 모달 컴포넌트 내부에서 모달 자신을 닫을 수 있어야 한다. 그리고 부모가 모달의 상태를 알고 있어야 한다.
parent가 close()함수를 직접 작성하여 my-modal에게 전달하는 방법이 있는데, 번거롭다. 어디선가 my-modal을 사용할때마다 닫기함수를 위한 로직을 구현해야한다. 그러면 컴포넌트의 재활용성이 떨어진다.
해법 : 양방향 데이터 바인딩 .sync
양방향 데이터 바인딩은 남용해서는 안된다. 이것때문에 2.0에서 sync가 삭제되었지만 2.2에서 다시 추가되었다. 재사용 가능한 컴포넌트에서 유용하다고 판단했기 때문이다.
.sync는 my-modal과 같이 잘 설계된, 재사용 가능한 컴포넌트에서 유용하게 쓰일 수 있다. 이제 .sync를 사용할 수 있도록 my-modal을 수정해보자.
my-modal.vue
this.$emit('update:visible', false) 코드가 추가되었다. 이제 모달 바깥을 클릭해서 모달을 닫는 동작도 쉽게 구현할 수 있게 되었다.
부모에서는 이렇게 사용하면 된다.
parent.vue
트랜지션등 몇 가지 스타일을 더 작성하면 남부럽지 않은 모달을 만들 수 있게 되었다. 부모 단계에서 vuex를 활용하면, 좀 더 범용적으로 컨트롤 될 수 있는 모달을 구현해볼 수도 있다.
이렇게 짜임새 있고 심플한 컴포넌트를 제작하고, 빈틈없는 테스트코드까지 완성하면 기분이 절로 좋아진다. 다른 개발자들을 위한 다양한 옵션을 추가하고 문서까지 만든다면 금상첨화.
이 글이 마음에 드셨다면 👏🏽👏🏽
