부모에서 데이터 변경을 처리하고 자식은 해당 데이터를 표현만 하는 방식을 이야기한다.
부모 컴포넌트인 index에서 일단은 props로 검색한 키워드 데이터를 자식 컴포넌트인 SearchInput으로 내려보낸다.
<template lang="">
<div class="app">
<main>
**<SearchInput :search-keyword="searchKeyword"></SearchInput>**
...
</main>
</div>
</template>
<script>
import axios from 'axios'
import SearchInput from '@/components/SearchInput.vue'
export default {
name: 'IndexPage',
components: { SearchInput },
data() {
return {
**searchKeyword: 'hi',**
}
},
...
</script>
<style scoped>
</style>
그럼 자식 컴포넌트는 해당 데이터를 받아 표현하는 역할만 수행하기 때문에 props로 받은 searchKeyword를 input 요소의 value와 바인드해서 나타내준다.
<template>
<div>
<input type="text" **:value="searchKeyword"** />
<!--prop으로 내려받은 searchKeyword가 바인드되어 input 창에 나타난다-->
<button>search</button>
</div>
</template>
<script>
export default {
name: 'SearchInput',
props: {
**searchKeyword**: {
type: String,
default: () => '',
},
},
}
</script>
<style scoped></style>
input요소의 input이라는 이벤트(내가 임의로 만든 이름)가 발생할 때마다 $emit을 사용하여 $event.target.value의 값을 위로 올릴 것이다.
<template>
<div>
<input
type="text"
:value="searchKeyword"
**@input="$emit('input', $event.target.value)"**
/>
<button>search</button>
</div>
</template>
<script>
export default {
name: 'SearchInput',
props: {
searchKeyword: {
type: String,
default: () => '',
},
},
}
</script>
<style scoped></style>
밑에서 위로 올라간 input 이벤트의 데이터들을 부모 컴포넌트에서 받아서 사용하기로 한다. updateSearchKeyword
메서드를 사용해서 searchKeyword
데이터를 바꾼다.
<template lang="">
<div class="app">
<main>
<SearchInput
:search-keyword="searchKeyword"
**@input="updateSearchKeyword"**
></SearchInput>
...
</main>
</div>
</template>
<script>
import axios from 'axios'
import SearchInput from '@/components/SearchInput.vue'
export default {
name: 'IndexPage',
components: { SearchInput },
data() {
return {
**searchKeyword**: 'hi',
}
},
...
methods: {
...
**updateSearchKeyword**(**keyword**) {
this.searchKeyword = **keyword**
},
},
}
</script>
<style scoped>
</style>
사실 이렇게 v-bind와 v-on 둘을 잘 조합한 게 v-model과 같은 역할을 하기는 한다.
v-model로 바꿔보자.
부모 컴포넌트
<template lang="">
<div class="app">
<main>
<!-- <SearchInput
:search-keyword="searchKeyword"
@input="updateSearchKeyword"
></SearchInput> -->
**<SearchInput v-model="searchKeyword"></SearchInput>**
...
</main>
</div>
</template>
자식 컴포넌트
자식 컴포넌트에서 v-model에 바인드 된 prop을 받고 싶다면 value
란 값을 사용하면 된다. 일반적으로 prop은 부모에서 정해준 이름을 가지고 와서 사용하지만, v-model은 그렇지 않다.
<template>
<div>
<input
type="text"
**:value="value"**
@input="$emit('input', $event.target.value)"
/>
<button>search</button>
</div>
</template>
<script>
export default {
name: 'SearchInput',
props: {
**value**: {
type: String,
default: () => '',
},
},
}
</script>
<style scoped></style>