자식의 자식 컴포넌트에게 데이터 넘겨주기
1. props
ChildComp.vue ⊂ ParentComp.vue ⊂ App.vue
App 컴포넌트가 자식 컴포넌트로 ParentComp를 가지고 있고 ParentComp가 자식 컴포넌트로 ChildComp를 가지고 있다고 할때 ChildComp도 역시 App 컴포넌트의 자식 컴포넌트가 된다. 이때 App 컴포넌트에서 데이터를 ChildComp에게 props로 보내주게 되면 props가 ParentComp를 거쳐갈 수 밖에 없다. 이렇게 사용하지 않을 props를 하위 컴포넌트에게 전달하기 위해 받는 현상을 props drilling이라고 한다.
예제
App 컴포넌트의 하위 컴포넌트인 ParentComp 에게 props로 msg를 전달해주었다.
<!-- App.vue -->
<template>
<ParentComp :msg="msg" />
</template>
<script>
import ParentComp from './components/ParentComp.vue';
export default {
name: 'App',
components: {
ParentComp,
},
data() {
return {
msg: 'Hello World',
};
},
};
</script>
ParentComp 컴포넌트에서 msg 데이터를 사용하지 않을거지만 ParentComp의 하위 컴포넌트인 ChildComp에게 전달하기 위해 props값을 부모 컴포넌트인 App에서 받아와 다시 전달해준다. props를 받아오는 자식 컴포넌트는 props 옵션을 만들어 props의 type과 props가 제대로 전달되지 않았을때 사용할 default 값을 지정해준다.
<!-- ParentComp.vue -->
<template>
<ChildComp :msg="msg" />
</template>
<script>
import ChildComp from './ChildComp.vue';
export default {
components: {
ChildComp,
},
props: {
msg: {
type: String,
default: '',
},
},
};
</script>
App 컴포넌트에서 생성한 msg 데이터를 받아온다.
<!-- ChildComp -->
<template>
<h1>Child (props): {{ msg }}</h1>
</template>
<script>
export default {
props: {
msg: {
type: String,
default: '',
},
},
};
</script>
2. provide와 inject
위의 예제와 같이 props를 사용해 데이터를 전달하면 props를 사용하지 않을 컴포넌트에서도 props를 전달받아야하는 번거로움이 있다. 이런 경우에 provide와 inject를 사용하면 부모 컴포넌트는 컴포넌트 계층 구조의 깊이와 상관없이 모든 자식 컴포넌트에 props drilling 없이 한번에 데이터를 전달할 수 있다. 이때 부모 요소는 데이터 제공을 위해 provide 옵션을 사용하고 자식 요소는 데이터 사용을 위해 inject 옵션을 사용한다.
부모 컴포넌트
자식 컴포넌트에게 전달해주고 싶은 데이터를 provide 함수에 등록해준다.
<script>
export default {
data() {
return {
data: 'This is data',
};
},
provide() {
return {
data: this.data,
};
},
};
</script>
자식 컴포넌트
부모 컴포넌트에게 받을 데이터를 inject 배열에 넣어준다.
<script>
export default {
inject: ['data'],
};
</script>
예제
ChildComp 컴포넌트에게 전달해줄 데이터 msg를 provide 함수에 등록한다.
<!-- App.vue -->
<template>
<ParentComp />
</template>
<script>
import ParentComp from './components/ParentComp.vue';
export default {
name: 'App',
components: {
ParentComp,
},
data() {
return {
msg: 'Hello World',
};
},
provide() {
return {
msg: this.msg,
};
},
};
</script>
provide로 등록한 데이터는 자식 컴포넌트를 지날 필요가 없으므로 사용하지 않을 데이터를 등록할 필요가 없어진다.
<!-- ParentComp.vue -->
<template>
<ChildComp />
</template>
<script>
import ChildComp from './ChildComp.vue';
export default {
components: {
ChildComp,
},
};
</script>
App 컴포넌트에서 Provide 함수로 등록한 데이터를 가져오기 위해 inject라는 옵션을 등록해주고 배열 안에 App 컴포넌트에서 가져올 데이터를 넣어준다.
<!-- ChildComp -->
<template>
<h1>Child (provide): {{ msg }}</h1>
</template>
<script>
export default {
inject: ['msg'],
};
</script>
computed 메서드를 사용해 반응형 데이터 전달해주기
provide와 Inject를 사용해 부모 컴포넌트의 데이터를 전달해줄 수 있지만 부모 컴포넌트에서 해당 데이터가 변경되었을때 업데이트된 데이터는 자식 컴포넌트에서 반영 되지 않는다. 이를 해결하기 위해 computed 메서드를 사용해 provide 함수 내에서 데이터를 연산해야한다.
예제
msg라는 데이터는 provide 함수에 등록되어 다른 자식 컴포넌트가 사용하고 있는 데이터다. 이 데이터는 버튼을 클릭했을때 변경되는데 provide 함수에 등록되어 있는 데이터기 때문에 데이터가 변경되어도 자식 컴포넌트에는 반영이 안된다. 이를 해결하기 위해 computed 메서드를 사용해준다.
<!-- App.vue -->
<template>
<button @click="msg = 'Bye World'">Click</button>
<h1>App: {{ msg }}</h1>
<ParentComp />
</template>
<script>
import ParentComp from './components/ParentComp.vue';
import { computed } from 'vue';
export default {
name: 'App',
components: {
ParentComp,
},
data() {
return {
msg: 'Hello World',
};
},
provide() {
return {
msg: computed(() => this.msg),
};
},
};
</script>
<!-- ChildComp -->
<template>
<h1>Child (provide/computed): {{ msg }}</h1>
</template>
<script>
export default {
inject: ['msg'],
};
</script>'Vue' 카테고리의 다른 글
| [Vue] 컴포지션 API 사용법 (0) | 2022.06.19 |
|---|---|
| [Vue] 요소나 컴포넌트를 참조할 수 있는 refs 사용법 (0) | 2022.06.18 |
| [Vue] Slot을 이용한 컨텐츠 제공 (0) | 2022.06.18 |
| [Vue] 이벤트를 상속시켜주는 Emit (0) | 2022.06.17 |
| [Vue] v-bind="$attrs"를 사용해 컴포넌트의 속성 상속시키기 (0) | 2022.06.17 |
댓글