react와 완전히 동일한 개념이다. props로 부->자 데이터를 넘겨주는 방식이다.
하지만 문법이 조금 다른데 알아보자.
kebab-case
로 적어주어야한다.<template>
<section>
<ul>
<friend-contact
name="정우"
phone-number="010-1234-5678"
email-address="정우@google.com"></friend-contact>
</ul>
</section>
</template>
그리고 이 속성값을 받은 컴포넌트에서 사용을 하려면 Vue 구성 객체의 속성값으로 props
를 추가해서 배열로 해당 값을 받아온다.
이때 속성값은 항상 문자열이여야하는데 만약 다른 type을 보내고 싶다면 쉽게 binding하면 그만이다. 아래와 같이 바인딩한다면 단순 type지정 뿐만 아니라 간단한 JS 로직도 써 넣을 수 있다. 즉, 동적바인딩이 가능하다.
<friend-contact
v-for="friend in friends"
:key="friend.id"
:name=friend.name
:phone-number="friend.phone"
:email-address="friend.email"
:is-favor=friend.favor
></friend-contact>
<template>
...
</template>
<script>
export default {
props:[
'name', 'phoneNumber', 'emailAddress'
],
...
}
</script>
kebab-case
로 넘겨받은 속성(props
)값은 .vue
에서 사용될 때 camelCase
로 바뀌서어 사용된다.kebab-case
는 유효하지 않은 JS 문법이기 때문에 camelCase
로 작성한다.camelCase
로 작성된 프로퍼티를 자동으로 해석해서 kebab-case
로 바꿔준다. 대시가 포함된 버전으로 바꿔 줍니다
2. data props나 computed props등 다른 속성값과 이름이 중복되면 안 된다.
this.
키워드로 참조하여 methods등 다른 속성값에서도 사용가능하다.<template>
...
</template>
<script>
export default {
props:{
name:String,
phoneNumber:String,
emailAddress:String,
isFavor:Boolean
},
...
}
</script>
지정 가능한 type들 : 문자열(String), 숫자(Number), 불리언(Boolean), 배열(Array), 객체(Object), 날짜(Date), 함수(Function), 심볼(Symbol)
또는 객체를 지정하여 type 이외에도 여러 제약을 줄 수 있다.
<script>
export default {
props:{
props:{
name:{
type:String,
require:true
},
phoneNumber:{
type:String,
require:true
},
emailAddress:{
type:String,
require:true
},
isFavor:{
type:String,
require: false,
default:"0",
validator:function (value) {
return value==='0'||value==='1'
}
}
},
},
...
}
</script>
예를 들어 require 속성을 줄 수 있고 이는 boolean으로 관리해야한다. 또한 default 속성으로 값이 넘어오지 않았을 때의 기본값을 설정해 둘 수 있다.
또한 validator 속성을 사용하여 특정 값만을 갖도록 지정할 수 있다. 여기서는 type은 String이지만 오직 0,1만을 갖을 수 있도록 만들었다.
조금 더 자세한 것은 공식문서에서도 확인할 수 있다.
위 사진을 보면 props로 부모에서부터 받아온 값인 "isFavor"를 자식 컴포넌트에서 그냥 변경하려고 하니 ESLint error가 발생하였다.
그러다면 자->부 로 lifting state up은 불가능한 것일까? 2가지 방법이 있다.
toggleFavor(){
// this.favor = !this.favor
this.$emit('toggle-favorite', this.id);
}
this
키워드 밑에 붙어있는 내장 메서드로써 emit
은 발산하다
라는 뜻을 갖고있다.이 메서드는 부모 컴포넌트에서 수신할 수 있는 커스텀 이벤트를 발생시켜 준다.
emit는 최소한 하나의 인수인 커스텀 이벤트의 이름을 요구한다.
this.$emit('kebab-case-method-name', 인수);
ps. 이벤트는 kebab-case로 작성하자.
<friend-contact
v-for="friend in friends"
:key="friend.id"
:name=friend.name
:phone-number="friend.phone"
:email-address="friend.email"
:is-favor=friend.favor
@toggle-favorite="toggleFavoriteStatus"
></friend-contact>
...
<script>
export default {
...
methods:{
toggleFavoriteStatus(friendId){
const selectedFriendId = this.friends.find(freind => freind.id === friendId);
selectedFriendId.favor = !selectedFriendId.favor
}
}
...
}
</script>
v-on
또는 @
예약어를 통하여 자식 컴포넌트로부터 이벤트를 속성값으로 listen 해주면 된다.<template>
...
<h2>{{name}} {{favor ? '즐찾' : ''}}</h2>
<button @click="toggleDetails">{{ detailAreVisible ? 'Hide' : 'Show'}} Detail</button>
<button @click="toggleFavor">{{ favor ? '삭제' : '추가'}}</button>
...
</template>
<script>
export default {
props:[
'name', 'phoneNumber', 'emailAddress', 'isFavor'
],
data(){
return{
detailAreVisible:false,
favor : this.isFavor // yo부분임!
}
},
methods:{
toggleDetails(){
this.detailAreVisible = !this.detailAreVisible
},
toggleFavor(){
this.favor = !this.favor
}
}
}
</script>