부모와 자식 컴포넌트 사이의 위계 단계가 굉장히 커질 때 **prop drilling
**이 발생할 수 있다. 이를 막아주기 위해 사용한다.
부모에서부터 먼 자식까지 prop drilling을 피해서 데이터를 전달하고 싶을 때, 부모에서 해당 데이터를 **provide
**하면 자식에서 이를 **Inject
**하여 사용할 수 있다.
부모의 부모
<template>
<div>
<**ProvideInjectChild** />
</div>
</template>
<script>
import ProvideInjectChild from './ProvideInjectChild.vue'
export default {
components: { ProvideInjectChild },
data() {
return {
items: ['A', 'B'],
}
},
**provide() {
return {
items: this.items,
}
},**
}
</script>
<style scoped></style>
부모
사실상 아무것도 하지 않아도 된다.
<template>
<div>
<**ProvideInjectChildChild**/>
</div>
</template>
<script>
import ProvideInjectChildChild from './ProvideInjectChildChild.vue'
export default {
components: {ProvideInjectChildChild},
}
</script>
<style scoped>
</style>
자식
inject를 통해 provided된 데이터를 받을 수 있다.
<template>
<div>itemLength : {{itemLength}}</div>
</template>
<script>
export default {
components: {},
**inject: ["itemLength"]**
}
</script>
<style scoped>
</style>
Inject할 때 provided 된 해당 데이터가 어느 부모 컴포넌트로부터 왔는지 파악하기 어려울 수 있다. 따라서 그렇게 많이 쓰이지는 않고, 너무 복잡하지 않은 경우에는 그냥 props를 사용하는 것이 추적하기에는 더 좋은 경우가 많다.
앞서서 prop drilling을 막기 위해 부모 데이터 중 일부를 provide해서 하위 손자(?) 컴포넌트에서 inject하는 방법으로 provide와 inject를 사용할 수 있다고 배웠다. 그렇다면 composition API에서 역시 이를 활용할 수 있을 것이다.
setup() 안에서 어떻게 하면 Props drilling을 피하기 위해 provide와 inject를 사용할 수 있을까?
// 부모 컴포넌트
<template>
<CompositionAPIInject/> // 자식 컴포넌트
</template>
<script>
**import {provide} from 'vue'**
import CompositionAPIInject from './CompositionAPIInject.vue'
export default {
components: {CompositionAPIInject},
setup() {
**provide('title', 'Vue.js project')** // title: 'Vue.js project'
}
}
</script>
자식 컴포넌트에서 inject를 import해 마치 메서드와 같이 사용할 수 있다.
<template>
<h1>{{title}}</h1>
</template>
<script>
**import {inject} from 'vue'**
export default {
setup() {
const title = inject('title')
return {title}
}
}
</script>