Provide / Inject

조지성·2022년 9월 21일
0

TIL

목록 보기
75/78
post-thumbnail

Prop Drilling

깊이 중첩된 자손 컴포넌트에 데이터를 전달해야 한다면 해당 자손 컴포넌트와 연관된 모든 자식 컴포넌트에게 동일한 prop를 전달
=> Prop Drilling

해당문제는 Vue3의 provideinject로 해결

Provide

  • 상위 컴포넌트 setup() 함수 내부에서 사용
  • provide() 함수는 두 개의 파라미터를 가짐
    • 첫 번째 파라미터는 주입 키 : 문자열 또는 Symbol이 될 수 있습니다. 주입 키는 하위 컴포넌트에서 주입된 값을 조회하는 데 사용.
    • 두 번째 파라미터는 제공된 값 : 값은 refs와 같은 반응성 데이터를 포함하여 모든 유형

Inject

  • 하위 컴포넌트 setup() 함수 내부에서 inject()함수 사용

Reactivity

  • Provide / Inject를 반응성 데이터로 제공할 때는 가능한 모든 변경을 Provider 내부에서 하는것이 좋음

Symbol 키 사용

  • 대규모 프로젝트에서 잠재적 충돌을 피하기 위해서 Symbol 키 사용

App-level Provide

컴포넌트에서 데이터를 제공하는 것 외에도 App-level에서 제공할 수도 있다.

예제

<template>
  <div class="container py-4">
    <div class="card">
      <div class="card-header">ProvideInject Component</div>
      <div class="card-body">
        <button @click="count++">Count++</button>
        <p>{{ appMessage }}</p>
        <Child></Child>
      </div>
    </div>
  </div>
</template>

<script>
import { inject, provide, readonly, ref } from "vue";
import Child from "./Child.vue";
export default {
  components: {
    Child,
  },
  setup() {
    const staticMessage = "static message";
    const message = ref("message");
    const count = ref(10);
    const updateMessage = (appendMessage) => {
      message.value = message.value + appendMessage;
    };
    provide("static-message", staticMessage);
    provide("message", { message: readonly(message), updateMessage });
    provide("count", count);

    const appMessage = inject("appMessage");
    return { count, appMessage };
  },

  mounted() {
    console.log(this.msg);
  },
};
</script>

<style lang="scss" scoped></style>
<template>
  <div class="card">
    <div class="card-header">Child Component</div>
    <div class="card-body">
      <p>{{ appMessage }}</p>
      <DeepChild></DeepChild>
    </div>
  </div>
</template>

<script>
import { inject } from "vue";
import DeepChild from "./DeepChild.vue";
export default {
  components: {
    DeepChild,
  },
  setup() {
    const appMessage = inject("appMessage");
    return { appMessage };
  },
};
</script>

<style lang="scss" scoped></style>
<template>
  <div class="card">
    <div class="card-header">Child Component</div>
    <div class="card-body">
      <p>{{ staticMessage }}</p>
      <p>{{ message }}</p>
      <p>{{ count }}</p>
    </div>
  </div>
</template>

<script>
import { inject } from "vue";

export default {
  setup() {
    const staticMessage = inject("static-message", "default-message");
    const { message, updateMessage } = inject("message");
    updateMessage("!");
    const count = inject("count");
    return { staticMessage, message, count };
  },
};
</script>

<style lang="scss" scoped></style>
profile
초보 개발자의 성장기💻

0개의 댓글