컴포넌트간의 데이터 전달

만약에 깊이 있는 컴포넌트에 데이터 전달 해야할 때는

props로는 너무 어려움..

Provide/Inject 를 그래서 사용한다

자식 컴포넌트에 데이터를 전달하려면

provide 함수를 사용한다.

Provide 함수

provide(문자열, 문자열)

root 컴포넌트 ㄴ ProvideInject ㄴ child ㄴ DeepChild

이렇게 되어있는 구조에서 ProvideInject 를 사용하여 DeepChild로 데이터를 전달할 것이다.

사용법

// ProvideInject.vue
setup() {
		const staticMessage = 'static message';
		const message = ref('message');
		const count = ref(10);
		provide('static-message', staticMessage);
		provide('message', message);
		provide('count', count);
		return {};
},

위와 같이 provider에 등록

// DeepChild.vue
setup() {
		const staticMessage = inject('static-message');
		const message = inject('message');
		const count = inject('count');

		return { staticMessage, message, count };
},

위와 같이 Inject 함수를 사용해서 가져올 수 있다

값을 입력하지 않았을 때, default value를 정의할 수도 있고

또 child에서 값을 바꿀 수도 있다

그러나 child에서 Provider 값을 바꿀 때는 그냥 막 바꾸기 보단, provider에서 update 함수를 만들어서 제공해주는 것이 좋다.

const message = ref('message');
const updateMessage = () => {
  message.value = message.value + '!';
};
provide('message', { message, updateMessage });

위와 같이 사용하며

const { message, updateMessage } = inject('message');
// message.value = message.value + '!';
// 이렇게하지말고, provider에서 업데이트 함수 제공하라!
updateMessage();

사용할 때는 구조분해 할당으로 가져와서 사용한다.

message.value = message.value + ‘!’;

그러나 이렇게 사용한다 해도 수정은 된다

기능은 열려있음

수정을 막으려면 readonly를 사용할 것.

provide('message', { message: readonly(message), updateMessage });

이렇게 사용하면 수정을 막아줄 수 있다.

Symbol

대규모 애플리케이션에서 다른 개발자와 함께 작업하는 경우 잠재적 충돌을 피하기 위해 Symbol 주입 키를 사용하는 것이 좋다.

Symbol()을 씀으로써 얘는 Provider에 저장할 애야

뭐 이런 느낌인가보다..

App-level Provide

vue dev tools에서

모든 컴포넌트는 App의 자식 컴포넌트임.

그러므로 main.js에서

app.provide('app-message', 'app message 입니다.');

이렇게 사용하면

const appMessage = inject('app-message');

어디서든 이렇게 가져와서 사용할 수 있다.

실무에서..

Provide/Inject를 실무에서 어떻게 사용할 것이냐

vue 2 의 경험이 있다면 알 것임 app 인스턴스에는 config.globlaProperty라는 애가 있음

mounted(){
  console.log(this.msg)
}

뭐 이렇게 사용할 수 있음.

그러나 vue 2의 경우에는 mounted라는 life cycle hook이 있어서 사용할 수 있었으나

vue3 에서는 setup에다가 위와 같이 사용할 수없으므로

provide를 쓴다…