개념
Vue component와 component의 데이터 전달을 하기 위한 방법 중 하나 이다.
Props의 주요 성격은 아래와 같다.
- component와 component는 부모와 자식 관계가 성립 되어야 한다.
- 단반향 데이터 흐름을 가진다.(one-way-down binding)
component와 component는 부모와 자식 관계가 성립 되어야 한다.
// parent component
<template>
<div>
<Child></Child>
</div>
</template>
<script>
import Child from "@/views/Child";
export default {
components:{
Child
}
}
</script>
👉 <Child></Child>
- 현재 parent component에 Child component를 불러와 주입 시켰다. 이렇게 parent compoent와 Child component를 부모와 자식 관계로 만들었다. 이제 Props를 사용 할 수 있게 된다.
- Props는 부모(parent compoent)에서 자식(Child component)에게 데이터 전달을 하기위해 사용 한다.
- 만약 부모, 자식 관계가 성립 되지 않는다면, Props로 데이터 전달은 불가능 하다.
단반향 데이터 흐름을 가진다.(one-way-down binding)
Props는 오직 부모에서 자식으로 전달되는 흐름을 가진다.
자식에서 부모로 데이터 전달은 Props를 사용할 수 없고 Emit을 사용해야 한다.
이런 이유는 자식 component가 실수로 데이터를 변경해 부모 component의 상태를 변경하는 것을 방지하기 위해서 이다.
또한, 부모component가 업데이트될 때마다 자식componennt의 props는 최신 값으로 새로고침 된다.
Props의 성격을 기억해두고 기본기 부터 사용법까지 자세히 알아보자.
Props 기본기
// parent component
<template>
<div>
<Child :childValue='value'></Child>
</div>
</template>
<script>
import Child from "@/views/Child";
export default {
components: {
Child
},
data() {
return {
value: 'superpil',
}
}
}
</script>
// child component
<template>
<div>
{{ childValue }}
</div>
</template>
<script>
export default {
props: ["childValue"],
created() {
console.log('this.childValue', this.childValue);
}
}
</script>
👉 <Child :childValue='value'></Child>
value
가 Child component에 전달 된다.- Child component에 전달 될 때
value
값이childValue
에 담겨서 전달 된다.
👉 props: { ... }
- perent component에 전달 받은
value
값은childValue
에 담겨 있다. - 이제 Child component에서는
this.childValue
로 값을 확인 할 수 있다.
👉 console.log(this.childValue)
- Parent component에서 받은 값(superpil)을 출력 한다.
위 Props기본기 예제의 데이터 전달 되는 흐름을 나타낸 다이어그램 이다.
Props의 타입
타입의 종류 및 타입 지정하기
props는 String 뿐만 아니라 다양한 타입을 전달 할 수 있다.
타입의 종류는 String, Number. Boolean, Array, Object, Function, Promise가 있으며, 잘못된 타입이 전달될 경우 콘솔에 에러 메세지를 뿜어 낸다.
props에 타입을 지정하기 위해서는 값을 전달 받는 component(예제에서는 child component)에서 타입을 지정하면 된다.
타입을 지정할 시 props의 데이터구조는 객체 형태 이다.
아래에 예제를 확인하면 쉽게 이해 할 수 있다.
숫자(Number) 전달
// parent component
<template>
<div>
<Child :childValue=2></Child>
</div>
</template>
// child component
<template>
<div>
{{ childValue }}
</div>
</template>
<script>
export default {
props: {
childValue: Number,
},
}
</script>
👉 props: { childValue: Number, }
- child component에서 Number 타입으로 받기 위한 설정 이다.
- Number타입 뿐만 아니라 다른 타입도 같은 형태로 설정 하면 된다.
배열(Array) 전달
// parent component
<template>
<div>
<Child :childValue="['a', 'b', 'c']"></Child>
</div>
</template>
// child component
<template>
<div>
{{ childValue }}
</div>
</template>
<script>
export default {
props: {
childValue: Array,
},
}
</script>
객체(Object) 전달
// parent component
<template>
<div>
<Child :childValue="{a: 'super', b:'pil'}"></Child>
</div>
</template>
// child component
<template>
<div>
{{ childValue }}
</div>
</template>
<script>
export default {
props: {
childValue: Object,
},
}
</script>
논리 자료형(Boolean) 전달
// parent component
<template>
<div>
<Child :childValue="true"></Child>
</div>
</template>
// child component
<template>
<div>
{{ childValue }}
</div>
</template>
<script>
export default {
props: {
childValue: Boolean,
},
}
</script>
타입 유효성 검사
// parent component
<template>
<div>
<Child :childValue="2"></Child>
</div>
</template>
// child component
<template>
<div>
{{ childValue }}
</div>
</template>
<script>
export default {
props: {
childValue: Boolean,
},
}
</script>
[Vue warn]: Invalid prop: type check failed for prop "childValue". Expected Boolean, got Number with value 2.
parent component에서 child component로 "2"를 전달한다.
하지만 child component는 전달 받는 값의 타입을 Boolean으로 설정 하여 위와 같은 에러가 발생 한다.
위 방법으로 전달 받는 타입을 타이트 하게 잡아 유효성 검사를 해도 좋지만, 반면에 유연하지 못한 단점이 있다.
Vue에서 쫌 더 유연한 방법으로 전달 받는 값을 컨트롤 할 수 있는 방법을 제공한다.
타입 복수로 지정
// parent component
<template>
<div>
<Child :childValue="'superpil'"></Child>
</div>
</template>
// child component
<template>
<div>
{{ childValue }}
</div>
</template>
<script>
export default {
props: {
childValue: {
type: [String, Number]
}
},
}
</script>
👉 childValue: { type: [String, Number] }
- String 또는 Number 값을 받을 수 있다.
default값 지정
// parent component
<template>
<div>
<Child :childValue=undefined></Child>
</div>
</template>
// child component
<template>
<div>
{{ childValue }}
</div>
</template>
<script>
export default {
props: {
childValue: {
type: Number,
default: 2
}
},
}
</script>
👉 <Child :childValue=undefined></Child>
👉 default: 2
- childValue값이 undefined일 경우 defalut값이 적용 된다.
- 주의할점은 default값은 undefined일 경우만 적용 된다. 만약, null, false는 default가 적용 되지 않고 해당 값이 적용 된다.
// parent component
<template>
<div>
<Child :childValue=undefined></Child>
</div>
</template>
// child component
<template>
<div>
<!-- { "super": "pil" } -->
{{ childValue }}
</div>
</template>
<script>
export default {
props: {
childValue: {
type: Number,
default() {
return {super: 'pil'}
}
}
},
}
</script>
👉 default() { return {super: 'pil'} }
- Array, Object타입일 경우 default를 설정하기 위해서 메소드 형태로 사용해야 한다.
유효성 검사 커스텀
// parent component
<template>
<div>
<Child :childValue=2></Child>
</div>
</template>
// child component
<template>
<div>
{{ childValue }}
</div>
</template>
<script>
export default {
props: {
childValue: {
type: Number,
validator(val) {
let isOk;
(val < 3) ? isOk = true : isOk = false;
return isOk;
}
}
},
}
</script>
👉 validator(val) { ... }
- childValue가 3보다 큰 경우 false값이 return되어 에러를 뿜어 낸다. 3보다 작은 경우 정상 처리 된다.
- 여기서 주의할 점은 validator메소드는 단순 validation체크의 역할을 할 뿐 조건에 맞게 childValue값을 변경 할 수 없다.
Props 사용 시 주의점
// parent component
<template>
<div>
<Child :childValue=2></Child>
</div>
</template>
// child component
<template>
<div>
{{ childValue }}
</div>
</template>
<script>
export default {
props: {
childValue: {
type: Number,
}
},
created() {
this.childValue = 20;
}
}
</script>
Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "childValue"
👉 this.childValue = 20
- 전달 받은 childValue를 child component에서 수정하면, 위와 같이 빨강색 에러를 보게 된다.
- 부모로 부터 전달 받은 값을 자식 component에서 수정 할 수 없다. 정확하게 말하면 수정은 가능하나 warn이 발생 한다.
- childValue값을 변경하기 위해서는 emit을 사용해 parent component에서 변경 할 수 있다.
Reference
'개발노트 > Vue' 카테고리의 다른 글
[Vue] Redirected when going ... via a navigation guard. (0) | 2021.08.29 |
---|---|
[Vue] Dom접근 하기 - $ref, $refs (0) | 2021.08.09 |
[Vue] 조건부 렌더링(v-if, v-show) (1) | 2021.08.04 |
[Vue] input에 숫자만 입력 가능하게 하기 (1) | 2021.08.02 |
[Vue] Naver 간편 로그인 (naverLogin_implicit-1.0.3.js) 구현 (2) | 2021.07.31 |
개발 기록
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!