props와 비슷한 개념인데 중간 컴포넌트를 거치지 않고 Root 컴포넌트에서 바로 해당 컴포넌트로 주입시킬 수 있다.
플러그인 없이 바로 사용 가능 (vue 내부 기능)
반응성을 따로 부여해야 함
조상과 후손 컴포넌트 관계에서만 사용 가능
플러그인으로 따로 설치해서 연결해야 함
반응형 상태(데이터) 제공
모든 컴포넌트 관계에서 사용 가능
모듈화 가능!
Provide/Inject를 사용할려면 Root에서 선언해줘야한다. 그래야 모든 후손 자식들이 사용 가능하다. 바로 이 점 때문에 Provide/Inject가 유용하지 않다. Root라는 조상 컴포넌트에는 서 해당 데이터를 사용하지 않는데 후손들을 쓰게하기 위해 지정해야하는 일이 생기기 때문이다. Root에 존재하지 않아도 되는 데이터가 굳이 존재하게 되는 셈이다.
그리고 Provide로 내린 데이터는 기본적으로 반응성을 가지지 않는다. 123이라는 데이터를 자식에게 내려서 자식도 123을 쓰고 있는데 부모쪽에서 1234로 데이터가 변경되었다해도 반응성을 가지지 않기때문에 자식 컴포넌트의 데이터는 그대로 123이다.
아래 예제에서 반응형데이터로 변경하는 방법을 통해 알아보자.
// 조상 컴포넌트
export default {
components: {
HelloWorld,
Brother
},
// 함수로 작성
// provide 지정
provide() {
return {
count: 0
}
},
data() {
return {
// 숫자 0에서 출발
count: 0
}
}
}
provide()
함수를 작성해주고 이 안에 후손들에게 줄 데이터를 명시한다.
// 후손 컴포넌트
<script>
export default {
// 나의 조상에게 받을 데이터를 배열에 입력
inject: ['count']
}
</script>
후손은 inject
를 사용하여 데이터를 받는다. 이때 데이터는 배열로 받는다.
provide로 제공받은 데이터는 기본적으로 반응형 데이터가 아니다.
그냥 밑에 데이터를 던지는 구조 밖에 안되는 것이다.
조상->후손으로 내려줄 때 computed
옵션을 통해 계산된 데이터로 반응성을 주입시켜줘야한다.
import { computed } from 'vue'
provide() {
return {
// 여기서 리턴되는 값이 반응형임
count: computed(() => this.count),
// provide로 제공
increase: this.increase
}
},
data() {
return {
// 숫자 0에서 출발
count: 0
}
},
// 현재 count데이터 주인은 부모에있다. 증가하는 Methods를 부모에다가 적어준다.
methods: {
increase() {
this.count += 1
}
}
}
</script>
// 자식 컴포넌트
<template>
<h1>{{ count }}</h1>
<button @click="increase">
INCREASE
</button>
</template>
// <!-- 버튼 누르면 1씩 증가(반응형 데이터 다루기) -->
<script>
export default {
// 나의 조상에게 받을 데이터를 배열에 입력
inject: ['count', 'increase']
}
</script>
3-1 다른 자식도 적용해서 재사용해보기
// 또 다른 자식 컴포넌트
<template>
<h1>{{ count }}</h1>
</template>
// <!-- 버튼 누르면 1씩 증가(반응형 데이터 다루기) -->
<script>
export default {
// 나의 조상에게 받을 데이터를 배열에 입력
inject: ['count']
}
</script>
increase 버튼을 누르면 자식1과 자식2의 count수가 똑같이 올라간다. 같은 조상에서 받은 데이터라서 연동 된다.
그런데 애초에 반응형 데이터를 제공하는 store를 사용하는 편이 좋다.