Vue/Vue.js 문법

Vue.js 문법 - Provide / Inject

IT Blue 2021. 7. 18. 20:04

 

예제 코드

 

App.vue

<template>
  <Parent :msg="message" />
</template>
<script>
import Parent from '~/components/Parent'

export default {
  components: {
    Parent
  },
  data() {
    return {
      message: 'Hello world!'
    }
  }
}
</script>

 

Parent.vue

<template>
  <Child :msg="msg" />
</template>
<script>
import Child from '~/components/Child'
export default {
	components: {
		Child,
	},
	props: {
		msg: {
			type: String,
			default: ''
		}
	}
}
</script>

 

Child.vue

<template>
  <div>
    {{ msg }}
  </div>
</template>
<script>
export default {
  props: {
    msg: {
      type: String,
      default: ''
    }
  }
}
</script>

 

결과

 

코드 이해하기

- App.vue 파일 data() 부분 message 문자 데이터를 정의

- 정의된 내용을 Parent.vue 파일을 거쳐서 Child.vue 에서 출력

- props 를 이용해서 데이터를 한 단계씩 내려주고 있다

- 이 경우에 두 컴포넌트 사이의 모든 컴포넌트에 props를 전달해야하므로 효율적이지 못하다

 

Provide / Inject

 

- 이러한 경우에 Provide / Inject 를 사용

- 모든 자식에 대한 종속성 제공자 역활을 함

- 부모 컴포넌트는 데이터 제공을 위해 Provide 옵션을 사용

- 자식 컴포넌트는 데이터 사용을 위해 Inject 옵션을 사용

 

App.vue

<template>
  <Parent />
</template>
<script>
import Parent from '~/components/Parent'

export default {
  components: {
    Parent
  },
  data() {
    return {
      message: 'Hello world!'
    }
  },
  provide() {
    return {
      msg: this.message
    }
  }
}
</script>

 

Parent.vue

<template>
  <Child />
</template>
<script>
import Child from '~/components/Child'
export default {
	components: {
		Child,
	}
}
</script>

 

Child.vue

<template>
  <div>
    {{ msg }}
  </div>
</template>
<script>
export default {
  inject: ['msg']
}
</script>

 

코드 이해하기

- parent.vue 에서 데이터를 거치지 않음

- child.vue 에서 inject 옵션을 통해서 App.vue 에 명시된 msg 데이터를 사용

 

주의사항

- Provide 를 사용할때는 반응성을 제공할 수 없다

- 그렇기 때문에 간단하게 데이터를 전달해서 한번 출력하게 만들거나

- 반응성을 유지하기 위해 추가 작업을 해야 한다

 

provide 반응성 유지를 위한 추가 작업

 

App.vue

import { computed } from 'vue'

/* .... 생략 .... */
provide() {
    return {
      msg: computed(() => {
        return this.message
      })
    }
  }

 

Child.vue

<template>
  <div>
    Child: {{ msg.value }}
  </div>
</template>