작업 진행 중에, props 정의나 provide inject 가 없는 상황인데
하위 컴포넌트에서 props 를 받아 프로세스를 진행하는 코드를 보고 정리를 합니다.
개인적으로는 협업이라면 상태관리 라이브러리(vuex, pinia ) 나 provide inject 를 사용하여
코드 추적의 비용을 줄이는 게 더 낫다고 생각합니다.
vue 에는 폴스루 속성이라는 게 있습니다.
https://ko.vuejs.org/guide/components/attrs
Vue.js
Vue.js - The Progressive JavaScript Framework
vuejs.org
예시에는 클래스이름, 스타일, id 의 속성이 하위 컴포넌트로 자동 상속되는 예시만 나와 있어서
미쳐 몰랐지만..
A => B => C 로 A 가 최상단(부모) C가 최하단(자식) 컴포넌트라면
B에서 props 정의를 명시적으로 하지 않는다면
$attrs 에 명시하지 않은 props 나 emit 도 함께 담겨져서 상속이 됩니다.
이를 "props drilling" 또는 "prop 전달"이라고 합니다.
<!-- A 컴포넌트 -->
<template>
<B :propA="valueA" :propB="valueB" customAttr="hello" @customEvent="handler" />
</template>
<script setup>
import { ref } from 'vue';
import B from './B.vue';
const valueA = ref('값A');
const valueB = ref('값B');
const handler = () => {
// 이벤트 처리 로직
};
</script>
<!-- B 컴포넌트 -->
<template>
<div>
<C v-bind="$attrs" />
</div>
</template>
<script setup>
import { useAttrs } from 'vue';
import C from './C.vue';
// $attrs에 접근하기 위해 useAttrs 훅 사용
const attrs = useAttrs();
// inheritAttrs: false 설정을 위해 defineOptions 매크로 사용
// 참고: defineOptions는 Vue 3.3+ 버전에서 사용 가능합니다.
defineOptions({
inheritAttrs: false
});
</script>
이렇게 하면
B컴포넌트에서 attrs 객체의 값은 다음과 같다.
{
propA: '값A',
propB: '값B',
customAttr: 'hello',
onCustomEvent: [Function: handler]
}
v-bind="$attrs"를 사용할 때의 장점은 다음과 같습니다.
장점:
1. 속성 전달: $attrs는 부모 컴포넌트에서 전달받은 모든 속성(props로 명시적으로 선언되지 않은 속성들)을 포함합니다. v-bind="$attrs"를 사용하면 이러한 모든 속성을 자식 컴포넌트(여기서는 C 컴포넌트)로 한 번에 전달할 수 있습니다.
2. 코드 간소화: 각 속성을 개별적으로 전달하는 대신 한 줄로 모든 속성을 전달할 수 있어 코드가 간결해집니다.
3. 유연성: B 컴포넌트가 어떤 속성을 받을지 미리 알 필요가 없습니다. A 컴포넌트에서 전달하는 모든 속성이 자동으로 C 컴포넌트로 전달됩니다.
4. 투명한 래퍼 컴포넌트: B 컴포넌트가 단순히 A와 C 사이의 중간 역할을 하는 경우, 이 방식을 통해 B 컴포넌트를 "투명한" 래퍼로 만들 수 있습니다.
5. 컴포넌트 간 의존성이 명시적으로 드러납니다.
6. 작은 규모의 애플리케이션에서는 간단하고 직관적입니다.
inheritAttrs: false 옵션과 함께 사용하면, B 컴포넌트의 루트 요소에 불필요한 속성이 적용되는 것을 방지하면서도 원하는 자식 컴포넌트(C)에게 모든 속성을 전달할 수 있습니다.
이 방식은 특히 고차 컴포넌트(HOC) 패턴이나 컴포넌트 구성을 할 때 유용하지만, 경우에 따라선 안티패턴이
될 수도 있습니다.
단점:
1. 깊은 컴포넌트 트리에서는 유지보수가 어려워질 수 있습니다.
2. 중간 컴포넌트들이 불필요한 props를 전달하게 됩니다.
3. 코드의 가독성이 떨어질 수 있습니다.
4. 컴포넌트 재사용성이 떨어질 수 있습니다.
다음과 같은 경우에는 props drilling을 피하는 것이 좋습니다
1. 컴포넌트 트리가 깊고 복잡할 때
2. 여러 컴포넌트에서 동일한 데이터에 접근해야 할 때
3. 중간 컴포넌트들이 전달만 하고 사용하지 않는 props가 많을 때
이러한 상황에서는 다음과 같은 대안을 고려할 수 있습니다:
1. Vuex나 Pinia 같은 상태 관리 라이브러리 사용
2. Provide/Inject API 사용
3. Composition API와 컴포지션 함수를 활용한 로직 분리
4. 이벤트 버스 또는 옵저버 패턴 사용 (복잡성 주의)
'Vue' 카테고리의 다른 글
[Vue] useAttrs( ) : 하위 컴포넌트로의 속성 전달 (Composition API) (0) | 2024.11.11 |
---|---|
[Vue] Pinia 의 활용법 (0) | 2024.09.03 |
[Vue3] 스와이프 와 캐러셀의 차이점, 캐러셀 구현 방법 (0) | 2024.08.16 |
[Vue] vue 개발을 위한 플러그 인 (vscode ) (0) | 2024.04.01 |
[vue3] route 와 routes 의 차이 (0) | 2023.04.22 |