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 직접 수정 금지 |