vue.js/Vue3 - 기본편

20. Props

DEV-Front 2024. 1. 29. 00:53
반응형

 

Props

 

UI나 레이아웃은 동일하지만 게시글의 제목, 내용 같은 데이터는 각각 다릅니다.

그럼 컴포넌트에 각각 제목, 내용 데이터를 전달해야 하는데 이때 Props를 사용하여 

컴포넌트로 데이터(속성)을 전달할 수 잇습니다.

 


Props란?

Props란? 컴포넌트에 등록할 수 있는 사용자 정의 속성 입니다. 블로그 게시글 컴포넌트에 사용자 정의 속성을

선언하면 이 컴포넌트를 사용하는 부모 컴포넌트에서 데이터 (속성)를 전달할 수 있습니다.


Props 선언

Vue 컴포넌트에는 명시적 Props 선언이 필요합니다. 왜냐하면 컴포넌트에 전달된 외부 props가 

fallthough 속성으로 처리되어야 함을 알 수 있습니다.


문자열 배열 선언

컴포넌트에 props 옵션을 사용하여 선언할 수 있습니다.


객체문법 선언

 

문자열 배열을 사용하여 props를 선언하는것 외에도 객체 문법을 사용하여 속성 타입과 함께 선언할 수도 있습니다.

 

 

props 선언시 key는 속성명이고 value는 속성 타입입니다.

더 자세히 선언하고 싶다면 value에 고급옵션인 객체를 선언할 수 있습니다.

Vue 스타일가이드 에서는 문자열로 간단히 선언하는것 보다, 객체 타입으로 더 디테일하게 선언하는것을 권장합니다.

 

 

 

객체 타입으로 선언할때는

  • type : String, Number, Boolean, Array, Object, Data, Function, Symbol 모든 기본 생성자 또는 모든 사용자 정의 타입이 올 수 있습니다. (예 : Person, Animal)
    그리고 (Number, String) 배열을 이용하여여러개의 타입을 선언할 수 있습니다.
  • default : 속성값이 비어있거나 undefined를 전달 받는 경우 기본값을 선언할 수 있습니다.
    그리고 객체 또는 배열 타입인 경우 기본값을 팩토리 함수를 사용하여 반환해야 합니다.
  • required : 속성이 필수값이라면 true로 해서 설정할 수 잇습니다.
  • validator : 속성값의 유효성 검사가 필요할 때 사용할 수 있습니다.

컴포넌트 사용시 type, required, validator 명시된 사항을 위반할 때 개발모드에서 콘솔 경고가 발생됩니다.

Type이 유효하지 않다는 경고 console

includes 함수를 사용하여 news나 notice가 포함되어 있는지 검사 할 수 있습니다.

 

 

그리고 객체나 배열의 default를 받을때는 기본값을 반환하는 story 함수 형태로 선언해야 합니다.


Props 사용

 

선언된 props를 <template>에서 바로 사용할 수 있습니다.

 

setup() 함수의 첫 번째 매개변수로 props 객체를 받아 사용할 수 있습니다.

 

컴포넌트 인스턴스(this)의 $props 객체로 접근할 수 있습니다 (Options API)

 

부모 컴포넌트에서 props 데이터를 넣을때 케밥 케이스나 카멜 케이스로 key값을 넣어도 데이터가 잘 나옵니다.

 

Vue 공식 문서에서는 선언할때는 카멜 케이스, props 전달할때는 케밥 케이스 사용을 권장하고 있습니다.


 

객체를 사용하여 다중 속성 전달

 

객체의 모든 속성을 props로 전달하려는 경우 v-bind에 전달인자(예, v-bind:prop-name) 없이 사용할 수 있습니다.

 

예를 들어, 다음과 같이 post 객체가 선언되어 있다고 가정하겠습니다.

 

아래 두가지 방법은 동일 합니다.

.

 


단방향 데이터 흐름

 

모든 props는 상위 속성과 하위 속성간에 단방향 바인딩으로 형성되어 있습니다.

만약 상위 속성이 업데이트되면 하위 속성도 업데이트 되지만 그 반대는 아닙니다.

이러한 성질은 하위 속성 변경 실수로 상위 속성을 변경하여 앱의 데이터 흐름을 이해하기 어렵게 만드는것을 방지합니다.

 

또한 상위 컴포넌트가 업데이트 될 때마다 하위 컴포넌트의 모든 props는 최신 상태도 초기화 됩니다.

그렇기 때문에 자식 컴포넌트 내부에서 props를 변경하지 않아야 합니다.

 

일반적으로 props를 하위 컴포넌트에서 변경하고 싶은 두 가지 경우가 있습니다.

 

1. prop은 초기 값을 전달하는데 사용됩니다. 자식 컴포넌트에서 속성 값을 로컬 데이터 속성으로 사용 하고자할때 입니다.

이 경우 prop을 초기 값으로 사용하는 로컬 변수를 선언하는 것이 가장 좋습니다.


객체 / 배열 props 업데이트

 

객체(objcet)나 배열(array)이 props로 전달되면 자식 컴포넌트에서는 prop 바인딩 (값 변경)을 변경할 수 없지만

객체 또는 배열의 중첩 속성은 변경할 수 있습니다. 이것은 javaScript에서 객체와 배열이 참조 타입(Reference Type)으로

전달되고 Vue가 이러한 변경을 방지하는것은 부당한 비용이 들기 때문입니다.

 

이러한 변경의 단점은 하위 컴포넌트가 상위 컴포넌트에 명확하지 않은 방식으로 상위 속성 업데이트 하게 되면

잠재적으로 향후 데이터 흐름을 추론하기 어렵게 만든다는 것입니다. 그렇기 때문에 가장 좋은 방법은

부모와 자식이 의도적으로 밀접하게 연관되어 있지 않는한 이러한 변경은 피하는 것입니다.

만약 변경이 필요하다면 자식 컴포넌트에서 emit을 이용하여 부모 컴포넌트가 스스로 변경을 수행할 수 있도록 이벤트를 내보내야 합니다.

 

ESLint에서는 자식 컴포넌트에서 props의 값을 변경하면 안된다고 에러를 내지만

Vue 화면단에서는 값이 김길동으로 잘 바뀌었다. 이런 점은 javaScript 특성상 어쩔수 없는 부분임으로, 개발시 조심해야한다.


Boolean Casting

 

Boolean 타입의 Props는 특별한 캐스팅 규칙이 있습니다. 

<MyComponent>가 다음과 같이 선언되어 있습니다.

 

boolean 타입의 속성은 사용하는것 만으로도 true를 전달하는 것과 동일하고,

사용하지 않으면 false를 전달하는것과 동일한 특별한 캐스팅 규칙이 있습니다.


<script setup>에서의 Props 사용방법 

 

<script setup> 은 Vue 3의 새로운 문법으로, 컴포넌트의 속성(props), 상태(data), 메소드(methods) 등을

간결하게 정의할 수 있도록 도와주는 문법입니다.

 

defineProps는 <script setup>에서 사용되는 특별한 함수로, 해당 컴포넌트에 전달된 props를 정의하는 역할을 합니다.

일반적인 컴포넌트에서는 props 옵션을 사용하여 props를 정의하지만,

<script setup>에서는 이를 더 간단하게 할 수 있도록 defineProps 함수를 사용합니다.

 

예를 들어, 다음은 일반적인 컴포넌트와 <script setup>을 사용한 컴포넌트의 예입니다.

<!-- 일반적인 컴포넌트 -->
<script>
export default {
  props: {
    msg: String
  }
}
</script>

<!-- script setup을 사용한 컴포넌트 -->
<script setup>
defineProps(['msg'])
</script>

 

defineProps(['msg'])msg라는 이름의 prop을 정의하는 것입니다.

이를 통해 해당 컴포넌트에서 props.msg로 prop에 접근할 수 있게 됩니다.

이를 사용함으로써 <script setup>을 사용한 컴포넌트의 코드가 더 간결해지고 가독성이 높아집니다.

 

defineProps를 사용하면 직접적으로 required, 유효성 검사(validation), 타입(type) 등의 속성을

명시적으로 설정할 필요가 없습니다.

 

<script setup>에서는 이러한 세부적인 설정을 자동으로 처리해줍니다.

defineProps는 컴포넌트에 전달된 props를 추론하고 자동으로 유효성 검사를 적용합니다.

만약에 부모 컴포넌트로부터 필수로 받아야 하는 prop이 전달되지 않으면, Vue는 경고를 통해 알려줄 것입니다.

 

예를 들어, 다음과 같이 defineProps를 사용한 코드에서는 명시적인 유효성 검사나 타입 지정이 필요하지 않습니다.

 
<script setup>
defineProps(['msg'])
</script>

부모 컴포넌트에서 이 컴포넌트를 사용할 때, msg prop을 전달하지 않으면 Vue는 경고를 통해 필수 prop이 전달되지 않았다고 알려줄 것입니다. 이는 Vue 3의 새로운 <script setup> 문법이 추론과 자동화를 강조하는 특징 중 하나입니다.

 

반응형