본문 바로가기

Front-end/Vue

Vue.js) 컴포넌트 - Provide, Inject

1. Provide, Inject

  • Provide: 부모 컴포넌트에서 'provide' 옵션을 사용하여 자식 컴포넌트에 데이터를 제공합니다.
  • Inject: 자식 컴포넌트에서 'inject' 옵션을 사용하여 부모 컴포넌트에서 제공한 데이터를 주입받습니다.

2. 사용예시

// App.vue
<template>
	<ParentComponent :prop="prop" />
</template>

<script>
import ParentComponent from './components/ParentComponent.vue';
import {computed} from 'vue';
export default {
	components: {
		ParentComponent,
	},
	data() {
		return {
			prop: 'This is props',			
		};
	},
	provide() {
		return {
			provide: 'This is provide',	
		};
	},
};
</script>

// ParentComponent
<template>
	<div>
		<child :prop="prop" />
	</div>
</template>

<script>
import Child from './ChildComponent.vue';
export default {
	components: {
		Child,
	},
	props: {
		prop: {
			type: String,
			default: '',
		},
	},
};
</script>

// ChildComponent
<template>
	<div>prop: {{ prop }}</div>
	<div>provide: {{ provide }}</div>
</template>

<script>
export default {
	props: {
		prop: {
			type: String,
			default: '',
		},
	},
	inject: ['provide'],
};
</script>
prop: This is props
provide: This is provide

위 코드와 같이 props로 데이터를 넘겨주게 되면 App -> Parent -> Child에 모두 거쳐 데이터를 전달하여하 하지만, 

provide 속성으로 데이터를 넘겨주게 되면 Child에 inject 속성을 사용하여 Parent를 거치지 않고 데이터를 바로 전달할 수 있습니다. provide는 data 속성과 동일하게 넘겨줄 데이터를 정의해 주면 됩니다. inject는 배열 형식으로 상위 컴포넌트 provide에 정의한 데이터 객체를 명시해 주어 사용할 수 있습니다.

 

3.provide의 반응성

// App.vue
<template>
	<div><button @click="prop = 'Props Changed!'">Prop Change</button></div>
	<div>
		<button @click="provide = 'Provide Changed!'">Provide Change</button>
	</div>

	<ParentComponent :prop="prop" />
</template>

<script>
import ParentComponent from './components/ParentComponent.vue';
export default {
	components: {
		ParentComponent,
	},
	data() {
		return {
			prop: 'This is props',
			provide: 'This is provide',
		};
	},
	provide() {
		return {
			provide: this.provide,
		};
	},
};
</script>

// ParentComponent.vue
<template>
	<div>
		<child :prop="prop" />
	</div>
</template>

<script>
import Child from './ChildComponent.vue';
export default {
	components: {
		Child,
	},
	props: {
		prop: {
			type: String,
			default: '',
		},
	},
};
</script>

// ChildComponent.vue
<template>
	<div>prop: {{ prop }}</div>
	<div>provide: {{ provide }}</div>
</template>

<script>
export default {
	props: {
		prop: {
			type: String,
			default: '',
		},
	},
	inject: ['provide'],
};
</script>

props로 내려받은 데이터는 버튼을 클릭했을 때 즉각적인 변경이 이루어 지지만, provide로 넘겨받은 데이터는 버튼을 클릭하여도 데이터가 변하지 않습니다. 즉, provide에 정의한 데이터는 반응성을 가지지 않습니다. 

 

3.provide 반응성 가지기

provide에 정의한 데이터가 반응성을 가지기 위해서는 computed 연산한 데이터를 리턴하여 반응성을 가지도록 할 수 있습니다. 아래는 예시 코드입니다.

// App.vue
<template>
	<div><button @click="prop = 'Props Changed!'">Prop Change</button></div>
	<div>
		<button @click="sprovide = 'Provide Changed!'">
			Static Provide Change
		</button>
	</div>
	<div>
		<button @click="aprovide = 'Provide Changed!'">
			Active Provide Change
		</button>
	</div>

	<ParentComponent :prop="prop" />
</template>

<script>
import ParentComponent from './components/ParentComponent.vue';
import {computed} from 'vue';
export default {
	components: {
		ParentComponent,
	},
	data() {
		return {
			prop: 'This is props',
			sprovide: 'This is static provide',
			aprovide: 'This is active provide',
		};
	},
	provide() {
		return {
			staticProvide: this.sprovide,
			activeProvide: computed(() => {
				return this.aprovide;
			}),
		};
	},
};
</script>

// ParentComponent.vue
<template>
	<div>
		<child :prop="prop" />
	</div>
</template>

<script>
import Child from './ChildComponent.vue';
export default {
	components: {
		Child,
	},
	props: {
		prop: {
			type: String,
			default: '',
		},
	},
};
</script>

// ChildComponent.vue
<template>
	<div>prop: {{ prop }}</div>
	<div>provide: {{ staticProvide }}</div>
	<div>active provide: {{ activeProvide }}</div>
</template>

<script>
export default {
	props: {
		prop: {
			type: String,
			default: '',
		},
	},
	inject: ['staticProvide', 'activeProvide', 'msg'],
};
</script>

App 컴포넌트에 provide 속성에 staticProvide, activeProvide를 정의하고 activeProvide에 computed를 사용하여 data에 정의된 aprovide를 리턴하도록 하였습니다. 버튼을 누르면 computed 사용한 active provide의 값이 바뀐 것을 알 수 있습니다. 

 

 

'Front-end > Vue' 카테고리의 다른 글

Vue.js) 컴포지션API - 반응형 데이터  (1) 2024.07.31
Vue.js) 컴포넌트 - Refs  (0) 2024.07.30
Vue.js) 컴포넌트 - Slot  (3) 2024.07.30
Vue.js) 컴포넌트 - Emit  (0) 2024.07.30
Vue.js) 컴포넌트 - 속성 상속  (2) 2024.07.29