IT/개발
[Vue] DefineModel
반응형
부모로부터 받은 props를 바로 input에 v-model로 바인딩해서 수정도 되게 하고 싶다!!
모달을 부모에서 띄웠는데 자식 컴포넌트에서 바로 제어하고 싶다!!
네 이제 됩니다.
기존에는 부모로부터 props로 받은 값을 자식컴포넌트에서 다이렉트로 v-model에 바인딩하는 게 안 됐었습니다. 이건 단방향 데이터 흐름(One-way data flow) 원칙 때문입니다.
단방향 데이터 흐름은 데이터의 변경이 한 방향으로만 이루어지도록 하는 원칙입니다.
즉, 부모 컴포넌트에서 자식 컴포넌트로 데이터가 전달되고, 자식 컴포넌트에서는 이 데이터를 변경할 수 없습니다. 만약 자식 컴포넌트에서 props 데이터를 변경할 수 있다면, 데이터의 출처가 불분명해지고 예기치 못한 부작용이 발생할 수 있습니다.
그런데 이 원칙때문에 내가 원하는 걸 개발하려면 돌고 돌아 개발을 했었어야 했어요.
props로 받고 다른 ref 속성의 변수에 담아서 수정하고 그 이후에 값을 emit 해서 동기화하는 방법을 썼습니다.
불편했어요.
또 다른 불편한 예로는 모달을 띄울 때 isShowModal 같은 props를 받아다가 닫기 처리를 해야할 때였어요.
emit으로 isShowModal을 부모로 올려서 false 처리해줘야했죠.
귀찮아요!

저만 느낀 게 아니었을까요?! 개발자들의 요구사항을 들어줬습니다.
더 유연한 개발 환경을 제공하기 위해서 Vue 3.3 버전부터는 defineModel이라는 매크로를 experimental 기능으로 쓸 수 있게 했다가 3.4 버전부터는 정식 피쳐로 쓸 수 있게 했습니다.
이제 defineProps, defineEmits로 두 번씩 설정해야 하는 번거로움이 없어졌어요.
그럼 어떻게 쓰는지 코드로 정리해 보겠습니다.
| 부모 컴포넌트
<template>
<div>
<button @click="openModal">Open Modal</button>
<MyModal v-model:isModalOpen="isModalOpen" v-model:modalData="modalData" />
</div>
</template>
<script setup>
import MyModal from './MyModal.vue';
const isModalOpen = ref(false);
const modalData = ref({
title: 'Modal Title',
content: 'This is the modal content.',
});
function openModal() {
isModalOpen.value = true;
}
</script>
| 자식 컴포넌트 (모달)
<template>
<div class="modal">
<div class="modal-header">
<h2 name="title">{{ modelValue.title }}</h2>
<button @click="closeModal">Close</button>
</div>
<div class="modal-body">
<input v-model="modelValue.content">
</div>
</div>
</template>
<script setup>
const modelValue = defineModel('modelValue');
const isModalOpen = defineModel('isModalOpen');
function closeModal() {
isModalOpen = false;
}
</script>
| 참고
반응형
'IT > 개발' 카테고리의 다른 글
[Vue] Router 이동할 때 페이지 스와이프 효과 주기 (68) | 2024.04.06 |
---|---|
[CSS] 버튼에 animation 적용하기 (59) | 2024.04.05 |
[NPM] Bundlephbia (60) | 2024.04.04 |
[CSS] Text를 더 다양하게 꾸며보자 (71) | 2024.04.04 |
[HTML] Video Auto Play (자동재생) 조건 (63) | 2024.04.03 |
공지 : 개발 포스팅 댓글은 질문만 부탁드립니다.