레슨 4 / 9·20분
폼 처리와 v-model
v-model 양방향 바인딩
v-model은 폼 입력과 데이터를 양방향으로 연결하는 디렉티브입니다. 입력값이 변경되면 데이터가 자동 업데이트되고, 데이터가 변경되면 입력 필드도 함께 갱신됩니다.
vue
<script setup lang="ts">
import { ref } from 'vue';
const name = ref('');
const email = ref('');
const age = ref(20);
const agree = ref(false);
const gender = ref('');
const hobbies = ref<string[]>([]);
const bio = ref('');
</script>
<template>
<form @submit.prevent="handleSubmit">
<!-- 텍스트 입력 -->
<input v-model="name" placeholder="이름" />
<input v-model="email" type="email" placeholder="이메일" />
<!-- 숫자 (자동 변환) -->
<input v-model.number="age" type="number" />
<!-- 체크박스: 단일 (boolean) -->
<label>
<input v-model="agree" type="checkbox" /> 약관 동의
</label>
<!-- 체크박스: 다중 (배열) -->
<label><input v-model="hobbies" type="checkbox" value="독서" /> 독서</label>
<label><input v-model="hobbies" type="checkbox" value="코딩" /> 코딩</label>
<label><input v-model="hobbies" type="checkbox" value="운동" /> 운동</label>
<!-- 라디오 버튼 -->
<label><input v-model="gender" type="radio" value="male" /> 남성</label>
<label><input v-model="gender" type="radio" value="female" /> 여성</label>
<!-- textarea -->
<textarea v-model="bio" placeholder="자기소개"></textarea>
<button type="submit" :disabled="!agree">가입</button>
</form>
</template>v-model 수식어
- •
v-model.lazy— input 대신 change 이벤트 시 동기화 (포커스를 벗어날 때) - •
v-model.number— 입력값을 자동으로 숫자로 변환 - •
v-model.trim— 앞뒤 공백 자동 제거
컴포넌트에서 v-model
커스텀 컴포넌트에서도 v-model을 지원할 수 있습니다. defineModel() (Vue 3.4+)을 사용하면 간단하게 구현됩니다.
vue
<!-- RatingInput.vue -->
<script setup lang="ts">
// defineModel: v-model 바인딩을 간단하게 구현
const rating = defineModel<number>({ default: 0 });
</script>
<template>
<div class="rating">
<button
v-for="n in 5"
:key="n"
@click="rating = n"
:class="{ active: n <= rating }"
>
{{ n <= rating ? '★' : '☆' }}
</button>
<span>{{ rating }}점</span>
</div>
</template>
<!-- 부모에서 사용 -->
<script setup lang="ts">
import RatingInput from './RatingInput.vue';
import { ref } from 'vue';
const score = ref(3);
</script>
<template>
<RatingInput v-model="score" />
<p>선택한 점수: {{ score }}</p>
</template>💡
Vue 3.4 이전에는 커스텀 v-model을 구현하려면 modelValue prop과 update:modelValue emit을 수동으로 정의해야 했습니다. defineModel()은 이 보일러플레이트를 제거해줍니다.