Vue provide/inject

정현승·2025년 1월 8일

Prop 드릴링

provide와 inject는 Vue.js에서 컴포넌트 간 데이터 전달을 단순화하기 위해 사용됩니다.
특히, 부모 컴포넌트와 하위 컴포넌트 간에 중첩 구조가 깊어지는 경우에 유용합니다.

Provide

export default {
  provide: {
    message: '안녕!'
  }
}

data()를 통해 선언된 데이터와 같이 인스턴스별 상태를 제공해야 하는 경우, provide는 함수 값을 사용해야 합니다

export default {
  data() {
    return {
      message: '안녕!'
    }
  },
  provide() {
    // 함수 구문을 사용하여 `this`에 접근할 수 있습니다.
    return {
      message: this.message
    }
  }
}

Inject

export default {
  inject: ['message'],
  created() {
    console.log(this.message) // 주입된 값
  }
}

inject는 컴포넌트 자체 상태보다 먼저 구성되므로, data()에서 주입된 속성에 접근할 수 있습니다

export default {
  inject: ['message'],
  data() {
    return {
      // 주입된 값을 기반으로 하는 초기 데이터
      fullMessage: this.message
    }
  }
}

inject시 기본 값 설정하기

export default {
  // 주입에 대한 기본값을 선언할 때
  // 객체 구문이 필요합니다.
  inject: {
    message: {
      from: 'message', // 주입 시 키와 같은 이름을 사용하는 경우 선택사항입니다.
      default: '이것은 기본 값 문자열 입니다.'
    },
    user: {
      // 생성하는 데 비용이 많이 드는 기본이 아닌 값 또는 컴포넌트 인스턴스마다
      // 고유해야 하는 값에 대해 팩토리 함수를 사용합니다.
      default: () => ({ name: '철수' })
    }
  }
}

반응형으로 만들기

provide로 공급한 데이터는 반응성을 갖지 않습니다.
inject로 받은 값을 바꿔도 화면에 반영되지 않습니다.
반응형으로 연결된 inject를 만들기 위해, computed() 함수를 사용하여 계산된 속성을 제공해야 합니다

import { computed } from 'vue'

export default {
  data() {
    return {
      message: '안녕!'
    }
  },
  provide() {
    return {
      // 계산된 속성을 명시적으로 제공
      message: computed(() => this.message)
    }
  }
}

심볼 키 사용하기

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

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

export default {
  provide() {
    return {
      [myInjectionKey]: {
        /* 제공할 데이터 */
      }
    }
  }
}
// 주입되는 곳의 컴포넌트에서
import { myInjectionKey } from './keys.js'

export default {
  inject: {
    injected: { from: myInjectionKey }
  }
}

0개의 댓글