Vue : Provide(제공) / Inject(주입)

JooSehyun·2024년 9월 10일
0

[Study]

목록 보기
44/56
post-thumbnail

vue 공식문서 (Provide-Inject 바로가기)


컴포넌트 예 ) <Parent> -> <Child> -> <DeepChild>


Prop 드릴링

일반적으로 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달해야 할 때 props를 사용합니다. props만 사용하면 전체 부모 체인에 동일한 prop을 전달해야 합니다.

Prop 드릴링

<Parent> -> <Child :data="'message'"> -> <DeepChild :data="'data'">

<Child> 컴포넌트는 이 prop가 전혀 필요하지 않을 수 있지만, <DeepChild>가 접근할 수 있도록 여전히 선언하고 전달해야 합니다. 더 긴 상위 체인이 있으면 그 과정에서 더 많은 컴포넌트가 영향을 받습니다. 이것을 "prop 드릴링"이라고 합니다.


Provide(제공) / Inject(주입)

우리는 provide와 inject로 props 드릴링을 해결할 수 있습니다. 부모 컴포넌트는 모든 자식 컴포넌트에 대한 의존성 제공자 역할을 할 수 있습니다. 하위 트리의 모든 컴포넌트는 깊이에 관계없이 상위 체인의 컴포넌트에서 제공(provide)하는 의존성을 주입(inject)할 수 있습니다.

<Parent> -> <DeepChild>


Provide(제공)

부모 컴포넌트에서 하위 컴포넌트에 데이터를 제공하려면 provide() 함수를 사용합니다.

<script setup>
	import { provide } from 'vue'

	provide(/* 키 */ 'message', /* 값 */ '안녕!')
</script>

provide() 함수는 두 개의 인자를 허용합니다. 첫 번째 인자는 주입 키라고 하며 문자열 또는 Symbol이 될 수 있습니다. 주입 키는 자식 컴포넌트에서 주입할 원하는 값을 조회하는 데 사용됩니다. 단일 컴포넌트는 다른 값을 제공하기 위해 다른 주입 키를 사용하여 provide()를 여러 번 호출할 수 있습니다.

두 번째 인자는 제공되는 값입니다. 값은 refs와 같은 반응 상태를 포함하여 모든 유형이 될 수 있습니다

import { ref, provide } from 'vue'

const count = ref(0)
provide('key', count)

Inject(주입)

부모 컴포넌트에서 제공하는 데이터를 주입하려면 inject() 함수를 사용하세요

<script setup>
	import { inject } from 'vue'

	const message = inject('message')
</script>

📄Parent.vue

// 📄Parent.vue

<script setup>
  import { ref, provide } from 'vue'
  import Child from './Child.vue'

  // ref를 제공함으로써 GrandChild는
  // 여기서 일어나는 변화에 반응할 수 있습니다.
  const message = ref('안녕')
  provide('message', message)
</script>

<template>
  <input v-model="message">
  <Child />
</template>

📄Child.vue

// 📄Child.vue

<script setup>
	import DeepChild from './DeepChild.vue'
</script>

<template>
  <DeepChild />
</template>

📄DeepChild.vue

// 📄DeepChild.vue
<script setup>
import { inject } from 'vue'

const message = inject('message')
</script>

<template>
  <p>
    손자에게 전하는 메시지: {{ message }}
  </p>
</template>

반응형으로 만들기

반응형 제공/주입 값을 사용할 때, 가능하면 제공자 내부에서 모든 변경사항을 반응성 상태로 유지하는 것이 좋습니다. 이렇게 하면 제공된 상태와 가능한 변화가 동일한 컴포넌트에 함께 배치되어 향후 유지 관리가 더 쉬워집니다.

주입 대상 컴포넌트에서 데이터를 업데이트해야 하는 경우가 있습니다. 이러한 경우 상태 변경을 담당하는 함수를 제공하는 것이 좋습니다.

<!-- 제공자 컴포넌트 내부 -->
<script setup>
import { provide, ref } from 'vue'

const location = ref('북극')

function updateLocation() {
  location.value = '남극'
}

provide('location', {
  location,
  updateLocation
})
</script>
<!-- 주입되는 컴포는트 내부 -->
<script setup>
import { inject } from 'vue'

const { location, updateLocation } = inject('location')
</script>

<template>
  <button @click="updateLocation">{{ location }}</button>
</template>

마지막으로, provide를 통해 전달된 데이터가 주입된 컴포넌트에 의해 변경될 수 없도록 하려면, 제공된 값을 readonly()로 래핑할 수 있습니다.

<script setup>
import { ref, provide, readonly } from 'vue'

const count = ref(0)
provide('read-only-count', readonly(count))
</script>

🐵 심볼 키 사용하기

위 예제에서 문자열 삽입 키를 사용했습니다. 많은 의존성 제공자가 있는 대규모 앱에서 작업하거나, 다른 개발자가 사용할 컴포넌트를 작성하는 경우, 잠재적 충돌을 피하기 위해 제공 키로 Symbol(심볼)을 사용하는 것이 가장 좋습니다.

심볼을 전용 파일로 내보내는 것이 좋습니다.

// keys.js
export const myInjectionKey = Symbol()
// 제공하는 곳의 컴포넌트에서
import { provide } from 'vue'
import { myInjectionKey } from './keys.js'

provide(myInjectionKey, {
  /* 제공할 데이터 */
})
// 주입되는 곳의 컴포넌트에서
import { inject } from 'vue'
import { myInjectionKey } from './keys.js'

const injected = inject(myInjectionKey)

👍해당 글은 vue 공식문서 기반으로 작성되었습니다.

0개의 댓글