PromleeBlog
sitemap
aboutMe

posting thumbnail
Vue 폼 입력 처리와 v-model - Vue 기본기 다지기 9편
Handling Form Inputs with v-model in Vue - Vue Basics Part 9

📅

🚀

들어가기 전에 🔗

웹 서비스를 만들 때 사용자의 정보를 입력받는 '폼(Form)'은 절대로 빼놓을 수 없는 기능입니다.
회원가입, 로그인, 게시글 작성, 댓글 달기 등 대부분의 상호작용이 폼을 통해 이루어지기 때문입니다.

오늘은 Vue.js가 얼마나 쉽고 강력하게 폼 입력을 처리하는지 보여주는, v-model에 대해 집중적으로 배워보겠습니다.
v-model을 사용하면 사용자가 입력 필드에 타이핑하는 값이 스크립트 내의 데이터와 실시간으로 동기화되며, 이것을
양방향 데이터 바인딩
이라고 부릅니다.

🚀

v-model이란? 🔗

v-model을 이해하려면 먼저
양방향 데이터 바인딩
이 무엇인지 알아야 합니다.

v-model은 이 양방향 데이터 바인딩을 단 한 줄의 코드로 구현해주는 아주 편리한 디렉티브입니다.

사실 v-model은 내부적으로 v-bindv-on을 합쳐놓은 것입니다.
예를 들어 아래 두 코드는 완전히 동일하게 동작합니다.
<!-- v-model을 사용한 경우 -->
<input v-model="searchText">
 
<!-- v-bind와 v-on으로 풀어쓴 경우 -->
<input :value="searchText" @input="event => searchText = event.target.value">
v-model 덕분에 우리는 복잡한 이벤트 처리 코드를 매번 작성할 필요 없이, 아주 간결하게 폼을 다룰 수 있습니다.
양방향 데이터 바인딩
양방향 데이터 바인딩

🚀

다양한 폼 요소와 v-model 🔗

v-model은 텍스트 입력창뿐만 아니라 체크박스, 라디오 버튼, 드롭다운 메뉴 등 거의 모든 종류의 폼 요소에서 사용할 수 있습니다.

1. 텍스트 입력 (input, textarea) 🔗

가장 기본적인 사용법입니다.
ref로 만든 반응형 변수에 v-model을 연결하면 됩니다.
<script setup>
import { ref } from 'vue'
const message = ref('')
</script>
 
<template>
  <p>메시지: {{ message }}</p>
  <input v-model="message" placeholder="메시지를 입력하세요" />
</template>
위 코드에서 입력창에 무언가를 타이핑하면, 그 내용이 <p> 태그에 실시간으로 나타나는 것을 볼 수 있습니다. textarea도 동일하게 사용할 수 있습니다.

2. 체크박스 (Checkbox) 🔗

체크박스는 두 가지 경우로 나뉩니다.

<script setup>
import { ref } from 'vue'
const isChecked = ref(false)
</script>
 
<template>
  <input type="checkbox" id="checkbox" v-model="isChecked" />
  <label for="checkbox">{{ isChecked }}</label> <!-- isChecked 값(true/false)이 출력됩니다. -->
</template>
<script setup>
import { ref } from 'vue'
const checkedNames = ref([]) // 빈 배열로 시작
</script>
 
<template>
  <div>선택된 이름: {{ checkedNames }}</div>
  <input type="checkbox" id="jack" value="잭" v-model="checkedNames">
  <label for="jack">잭</label>
  <input type="checkbox" id="john" value="존" v-model="checkedNames">
  <label for="john">존</label>
</template>
사용자가 체크박스를 선택하면 해당 valuecheckedNames 배열에 추가되고, 체크를 해제하면 배열에서 제거됩니다.

3. 라디오 버튼 (Radio) 🔗

라디오 버튼은 여러 개 중 하나만 선택할 때 사용하며, 선택된 항목의 value를 하나의 변수에 연결합니다.
<script setup>
import { ref } from 'vue'
const picked = ref('')
</script>
 
<template>
  <div>선택: {{ picked }}</div>
  <input type="radio" id="one" value="첫 번째" v-model="picked" />
  <label for="one">첫 번째</label>
  <input type="radio" id="two" value="두 번째" v-model="picked" />
  <label for="two">두 번째</label>
</template>

4. 드롭다운 (Select) 🔗

드롭다운 메뉴(select)도 라디오 버튼과 비슷하게 선택된 <option>value를 변수에 연결합니다.
<script setup>
import { ref } from 'vue'
const selected = ref('')
</script>
 
<template>
  <div>선택됨: {{ selected }}</div>
  <select v-model="selected">
    <option disabled value="">하나를 선택하세요</option>
    <option>가</option>
    <option>나</option>
    <option>다</option>
  </select>
</template>

🚀

v-model을 더 편리하게 만드는 수식어 🔗

v-model에는 특별한 기능을 추가하는
수식어(Modifiers)
를 붙일 수 있습니다.
자주 사용되는 세 가지를 소개합니다.
➡️

.lazy 🔗

기본적으로 v-modelinput 이벤트가 발생할 때마다, 즉 키보드를 누를 때마다 데이터를 업데이트합니다.
.lazy 수식어를 붙이면 change 이벤트가 발생한 후에(주로 입력창에서 포커스가 벗어났을 때) 데이터를 업데이트합니다.
실시간 동기화가 불필요할 때 유용합니다.
<input v-model.lazy="message">
➡️

.number 🔗

사용자의 입력을 자동으로 숫자로 변환해 줍니다.
v-model은 기본적으로 모든 입력을 문자열로 다루기 때문에, 숫자 값을 다룰 때 이 수식어가 없으면 parseInt() 같은 함수를 직접 써야 합니다.
<input v-model.number="age" type="number">
➡️

.trim 🔗

사용자가 입력한 값의 앞뒤 공백을 자동으로 제거합니다.
아이디나 이메일 입력창에 유용합니다.
<input v-model.trim="username">

🚀

폼 제출 처리하기 🔗

사용자가 입력을 모두 마친 후 '제출' 버튼을 누르면, 우리는 그 데이터를 어딘가로 보내야 합니다.
이때는 <form> 태그의 submit 이벤트를 이용합니다.

여기서 중요한 점은, submit 이벤트는 기본적으로 페이지를 새로고침한다는 것입니다.
우리는 페이지 새로고침 없이 데이터를 처리하고 싶기 때문에, @submit.prevent처럼 .prevent 수식어를 붙여 기본 동작을 막아주어야 합니다.
<script setup>
import { ref } from 'vue'
 
const username = ref('')
const password = ref('')
 
function handleSubmit() {
  // .prevent 덕분에 페이지가 새로고침되지 않습니다.
  alert(`제출된 아이디: ${username.value}, 비밀번호: ${password.value}`)
  // 여기서 axios 등을 이용해 서버로 데이터를 보낼 수 있습니다.
}
</script>
 
<template>
  <form @submit.prevent="handleSubmit">
    <input v-model="username" placeholder="아이디">
    <input v-model="password" type="password" placeholder="비밀번호">
    <button type="submit">제출</button>
  </form>
</template>
이제 handleSubmit 함수 안에서 사용자가 입력한 모든 데이터를 안전하게 다룰 수 있습니다.

🚀

결론 🔗

오늘은 Vue의 v-model을 이용해 사용자의 입력을 손쉽게 다루는 방법을 배웠습니다.

참고 🔗