Vue2 훑어보기

date
May 23, 2022
slug
start-vue
author
status
Public
tags
summary
type
Post
thumbnail
category
updatedAt
Aug 3, 2025 02:12 PM

Props – 컴포넌트 간 단방향 데이터 흐름

Vue는 컴포넌트 기반 구조이기 때문에 각 컴포넌트는 독립적인 유효 범위(scope) 를 갖습니다.
즉, 부모와 자식 컴포넌트 간에도 데이터를 직접 접근할 수 없고, Vue의 규칙적인 통신 방식을 통해서만 전달해야 합니다.

Props의 역할

  • 부모 → 자식으로 데이터를 전달하는 유일한 공식적인 방법
  • 자식은 전달받은 prop읽기 전용으로 사용
// 자식 컴포넌트 정의 Vue.component('blog-post', { props: ['title'], template: '<h3>{{ title }}</h3>' }) // 부모 컴포넌트 템플릿 <blog-post :title="hello"></blog-post>

⚠️ 단방향 바인딩 원칙

  • 부모가 prop을 변경하면 자식에게 반영됨
  • 반대로, 자식이 prop을 직접 변경하는 것은 금지됨 (Vue는 경고 메시지를 띄움)
자식이 prop을 직접 변경하면 데이터 흐름이 복잡해지고, 디버깅이 어려워짐
 

자식 컴포넌트에서 prop을 수정하고 싶은 경우

Vue에서 권장하는 방법은 다음과 같습니다:

1. prop을 로컬 데이터로 초기화 후 수정

props: ['initialCounter'], data() { return { counter: this.initialCounter } }
이 방법은 초기값만 prop으로 받고, 이후엔 자식 컴포넌트 내부에서 관리하는 형태

2. computed로 변형해서 사용 (원본은 그대로 유지)

props: ['size'], computed: { normalizedSize() { return this.size.trim().toLowerCase() } }
원본 데이터를 변경하지 않고, 가공된 데이터를 사용해야 할 때 유용

3. $emit으로 부모에 이벤트 전달 (데이터 변경 요청)

// 자식 컴포넌트 <template> <button @click="$emit('update:title', 'new title')">Change Title</button> </template> // 부모 컴포넌트 <blog-post :title="title" @update:title="title = $event"></blog-post>
이 방식은 Vue 3의 v-model 커스텀 바인딩 패턴과 연결됩니다 (아래에서 자세히 설명)
 

v-model – Vue의 양방향 데이터 바인딩

v-model은 사용자 입력과 Vue 인스턴스의 데이터를 자동으로 동기화하는 디렉티브입니다.

기본 사용 예시

<input v-model="inputText" />
new Vue({ data: { inputText: '' } })
사용자가 input에 타이핑하면 inputText가 자동으로 업데이트됨
반대로 inputText를 변경하면 input 필드 값도 즉시 갱신됨
 

내부적으로는 아래 두 개가 결합된 것

<input:value="inputText" @input="inputText = $event.target.value" />
즉, v-model = v-bind:value + v-on:input
 

입력 유형별 v-model 동작

입력 요소
바인딩 대상
이벤트
<input>
value
input
<checkbox>
checked
change
<select>
value
change
 

v-model 관련 수식어

수식어
설명
.lazy
change 이벤트 이후 동기화 (기본은 input 이벤트)
.number
입력값을 자동으로 숫자로 형변환
.trim
입력값의 앞뒤 공백 제거
<input v-model.lazy="msg"> <input v-model.number="age" type="number"> <input v-model.trim="comment">
 

v-model의 한계 – 한국어 입력 문제

  • 한글, 일본어 등 IME(입력기)를 사용하는 언어에서는 조합 중인 입력이 반영되지 않거나 지연될 수 있음
  • 이럴 경우 v-model 대신 아래와 같이 직접 바인딩하는 것이 더 안정적임
<input:value="inputText" @input="inputText = $event.target.value" />
 

양방향 데이터 바인딩 (Two-way Binding)

개념

  • Vue 인스턴스의 데이터 ↔ 사용자 입력(UI)동기화
  • 즉, 데이터가 변경되면 DOM이 갱신되고, 사용자의 입력도 실시간으로 반영됨

Vue에서의 구성

  • v-model로 DOM ↔ 데이터 연결
  • v-on으로 사용자 이벤트 처리
 

Vue 3에서의 v-model 변화

커스텀 컴포넌트에 v-model을 쓸 때

Vue 3에서는 v-model로 바인딩할 prop 이름을 커스터마이징 가능
<!-- 부모 컴포넌트 --> <custom-input v-model:title="bookTitle" /> <!-- 자식 컴포넌트 --> props: ['title'], emits: ['update:title']
이 방식은 복잡한 컴포넌트 구조에서도 양방향 데이터 바인딩을 안전하게 유지할 수 있게 해줍니다.
 

요약

항목
요약
props
부모 → 자식 데이터 전달 (단방향, 읽기 전용)
v-model
사용자 입력과 데이터 동기화 (양방향 바인딩)
양방향 바인딩
Vue에서는 v-model, v-on 등으로 구현됨
주의사항
IME 입력 이슈, 객체 참조 주의, prop 직접 수정 금지