[Vue3] props

Dohee Kang·2023년 3월 4일
0

Vue

목록 보기
17/28

props는 컴포넌트를 사용할 때 데이터를 전달하기 위해 사용한다.

1. props 선언

  • propsprops 옵션을 사용하여 선언한다.
  • 객체 선언 문법
    • key : props의 이름
    • value : 값이 될 데이터의 타입에 해당하는 생성자 함수 (String, Number ...)
// 문자열 배열
export default {
  props: ['foo'],
  created() {
    // props는 `this`에 노출됩니다.
    console.log(this.foo)
  }
}

// 객체
export default {
  props: {
    title: String,
    likes: Number
  }
}

2. props 네이밍

  • kebab-case를 사용하면 아래와 같이 작성해야 하는 번거로움이 있기 때문에 camelCase를 사용한다.
    • kebab-case 작성 : obj['kebab-case']
    • camelCase 작성 : obj.camelCase
export default {
  props: {
    greetingMessage: String
  }
}
  • 기술적으로 props를 자식 컴포넌트에 전달할 때 camelCase를 사용할 수 있지만 camelCase로 선언된 props 속성이여도 HTML 관례에 맞게 kebab-case로 표기하여 사용한다.
<MyComponent greeting-message="안녕!" />

3. 정적 Props와 동적 Props

<!-- 정적 Props -->
<BlogPost title="Vue와 함께한 나의 여행" />

<!-- 동적 Props -->
<BlogPost :title="post.title" />

4. 다양한 타입의 값 전달

  • 위 예제는 문자열 값을 전달하였지만 어떠한 타입의 값도 props로 전달할 수 있다.
  • 하지만 자바스크립트 표현식임을 알려주려면 v-bind 혹은 콜론(:)을 사용해야 한다.
<!-- Number Type -->
<BlogPost :likes="42" />

<!-- Boolean Type -->
<!-- 값이 없으면 true로 간주 -->
<BlogPost is-published />
<BlogPost :is-published="false" />

<!-- Array Type -->
<BlogPost :comment-ids="[234, 266, 273]" />

<!-- Object Type -->
<BlogPost
  :author="{
    name: '신형만',
    company: '떡잎 상사'
  }"
/>

5. 객체로 여러 속성 바인딩

  • 객체의 모든 속성을 props로 전달하려면 인자 없이 v-bind를 사용하여 전달할 수 있다.
<template>
<!-- 모두 같은 내용을 전달하는 것이다. -->
<BlogPost v-bind="post" />
<BlogPost :id="post.id" :title="post.title" />
</template>

<script>
export default {
  data() {
    return {
      post: {
        id: 1,
        title: 'Vue와 함께하는 나의 여정'
      }
    }
  }
}
</script>

6. 단방향 데이터 흐름

  • 모든 props는 자식 속성과 부모 속성 사이에 하향식 단방향 바인딩을 형성한다.
    • 하향식 단방향 바인딩 : 부모 컴포넌트에서 자식 컴포넌트로 props 전달 (자식 -> 부모는 안됨)
  • 부모 컴포넌트가 업데이트 될 때 자식 컴포넌트의 모든 props가 업데이트된다. 따라서 자식 컴포넌트 내에서 props를 변경하지 않아야 한다. (자식 컴포넌트에서 props 변경 시 경고)

🧐 다음의 경우 props를 어떻게 변경하는 것이 좋을까?
1. props를 초기값을 전달하기 위해 사용되며, 자식 컴포넌트는 추후에 로컬 데이터 속성으로 사용하려고 하는 경우

  • 이 경우 props를 초기값으로 사용하는 로컬 데이터 속성을 정의하는 것이 좋다.
  1. props의 변환이 필요한 원시값으로 전달되는 경우
  • 이 경우 props의 값을 사용하여 계산된 속성을 정의하는 것이 좋다.

아래 예시는 1번과 관련된 예시이다.

  • 부모 컴포넌트(App)에 count0으로 할당하고 props명을 initCount로 하여 자식 컴포넌트(ChildComponent)에 count값을 전달해 해당 값을 <template>에 출력한 상태이다.
  • 하단에 첨부된 사진을 참고하여 결과물 확인
<!-- App.vue -->
<template>
  <ChildComponent :initCount="count" />
  <p>count: {{ count }}</p>
  <button type="button" @click="count++">Click</button>
</template>

<script>
import ChildComponent from './components/ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      count: 0
    }
  }
}
</script>

<!-- ChildComponent.vue -->
<template>
  <p>initCount: {{ count }}</p>
</template>

<script>
export default {
  props: ['initCount'],
  data() {
    return {
      count: this.initCount
    }
  }
}
</script>
  • 자식 컴포넌트의 값은 초기값은 그대로 유지되고, 부모 컴포넌트의 값은 1씩 증가하는 것을 확인할 수 있다.
  • props.initCountcount의 초기값으로 사용되고 추후 props가 갱신되어도 값이 업데이트 되지 않는 것을 알 수 있다.

아래 예시는 2번과 관련된 예시이다.

  • 부모 컴포넌트에서 자식 컴포넌트로 size를 전달해 자식 컴포넌트에서 해당 값을 계산한 상태이다.
  • 하단에 첨부된 사진을 참고하여 결과물 확인
<!-- App.vue -->
<template>
  <ChildComponent :size="size" />
  <p>size:{{ size }}</p>
</template>

<script>
import ChildComponent from './components/ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      size: ' A B C D E F '
    }
  }
}
</script>

<!-- ChildComponent.vue -->
<template>
  <p>childSize:{{ childSize }}</p>
</template>

<script>
export default {
  props: ['size'],
  data() {
    return {
      childSize: this.size.trim().toLowerCase()
    }
  }
}
</script>
  • props값이 잘 계산되어 normalizedSize에 출력된 것을 확인할 수 있다.
profile
오늘은 나에게 어떤 일이 생길까 ✨

0개의 댓글