Reese-log
  • About
  • Blog

© 2025 Reese. All rights reserved.

2022년 5월 23일

Vue2 훑어보기


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

Vue는 컴포넌트 기반 구조이기 때문에 각 컴포넌트는 독립적인 유효 범위(scope) 를 갖습니다.

즉, 부모와 자식 컴포넌트 간에도 데이터를 직접 접근할 수 없고, Vue의 규칙적인 통신 방식을 통해서만 전달해야 합니다.

Props의 역할

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

    ⚠️ 단방향 바인딩 원칙

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

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

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

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

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

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

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

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

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

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

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

    기본 사용 예시

    html
    
    <input v-model="inputText" />
    javascript
    new Vue({
      data: {
        inputText: ''
      }
    })
    사용자가 input에 타이핑하면 inputText가 자동으로 업데이트됨

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

    html
    
    <input:value="inputText"
      @input="inputText = $event.target.value"
    />
    

    즉, v-model = v-bind:value + v-on:input

    입력 유형별 v-model 동작

    입력 요소바인딩 대상이벤트
    <input>valueinput
    <checkbox>checkedchange
    <select>valuechange

    v-model 관련 수식어

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

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

  • 한글, 일본어 등 IME(입력기)를 사용하는 언어에서는 조합 중인 입력이 반영되지 않거나 지연될 수 있음
  • 이럴 경우 v-model 대신 아래와 같이 직접 바인딩하는 것이 더 안정적임
  • html
    <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 이름을 커스터마이징 가능

    plain text
    1<!-- 부모 컴포넌트 -->
    2<custom-input v-model:title="bookTitle" />
    3
    4<!-- 자식 컴포넌트 -->
    5props: ['title'],
    6emits: ['update:title']
    이 방식은 복잡한 컴포넌트 구조에서도 양방향 데이터 바인딩을 안전하게 유지할 수 있게 해줍니다.

    요약

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