💻 Vue에서 여러 컨테이너 다루기: v-show
, v-if
, :is
, keep-alive
사용법과 차이점
Vue로 개발하다 보면, 여러 컨테이너(컴포넌트)를 조건에 따라 보이거나 숨기거나, 동적으로 전환하는 상황이 자주 발생합니다. 이를 효과적으로 처리하기 위한 주요 도구로는 v-show
, v-if
, :is
, 그리고 keep-alive
가 있습니다. 이번 포스팅에서는 이들을 사용하는 방법과 각 방법의 차이, 동적 컴포넌트 전환 시 서로 다른 props
전달 방법과 동적으로 이벤트 메서드를 처리하는 방법을 포함해 자세히 알아보겠습니다.
💻 1. v-if
: 조건에 따라 컴포넌트를 추가/제거
v-if
는 조건이 true
일 때 컴포넌트를 DOM에 추가하고, 조건이 false
일 때 컴포넌트를 DOM에서 완전히 제거합니다. 다시 렌더링될 때는 초기 상태로 돌아가기 때문에, 컴포넌트를 추가/제거할 때 상태가 초기화되는 것이 필요한 경우 적합합니다.
📄 v-if
예시 코드
<template>
<div>
<button @click="showComponent = !showComponent">컴포넌트 보이기/숨기기</button>
<ChildComponent v-if="showComponent" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
data() {
return {
showComponent: true
};
}
}
</script>
- 장점: 컴포넌트를 DOM에서 완전히 제거함으로써 성능 최적화 가능.
- 단점: 컴포넌트를 제거하고 다시 렌더링할 때 상태가 초기화됨.
- 사용 시기: 상태가 초기화되어야 할 때, 예를 들어 폼 데이터 리셋이나 탭 전환 시 페이지 초기화가 필요할 때 적합합니다.
💻 2. v-show
: 상태 유지한 채 컴포넌트 숨기기/보이기
v-show
는 컴포넌트를 DOM에 유지한 채로, 조건에 따라 CSS를 사용해 보이거나 숨깁니다. 컴포넌트는 계속 DOM에 남아 있으므로, 상태가 유지됩니다.
📄 v-show
예시 코드
<template>
<div>
<button @click="isVisible = !isVisible">컴포넌트 보이기/숨기기</button>
<ChildComponent v-show="isVisible" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
data() {
return {
isVisible: true
};
}
}
</script>
- 장점: 상태가 유지된 상태로 컴포넌트를 빠르게 보이거나 숨길 수 있음.
- 단점: 컴포넌트가 DOM에 계속 남아 있기 때문에, 메모리 사용량이 증가할 수 있음.
- 사용 시기: 상태를 유지한 채로 빠르게 전환할 필요가 있을 때, 예를 들어 탭 전환에서 탭의 상태가 그대로 유지되어야 하는 경우 적합합니다.
💻 3. :is
: 동적으로 컴포넌트 전환 및 props
동적 전달
:is
는 여러 컴포넌트 중 하나를 동적으로 선택해서 렌더링할 수 있게 해줍니다. 또한, 동적으로 전환되는 컴포넌트에 서로 다른 props
를 전달할 수 있습니다. 이를 통해 상황에 맞게 다른 데이터를 각 컴포넌트에 넘겨줄 수 있습니다.
📄 :is
와 props
동적 전달 예시 코드
<template>
<div>
<button @click="changeComponent('Component1', { propA: '데이터 A' })">컴포넌트 1</button>
<button @click="changeComponent('Component2', { propB: '데이터 B' })">컴포넌트 2</button>
<!-- 동적 컴포넌트 및 props 전달 -->
<component :is="currentComponent" v-bind="currentProps" />
</div>
</template>
<script>
import Component1 from './Component1.vue';
import Component2 from './Component2.vue';
export default {
data() {
return {
currentComponent: 'Component1',
currentProps: {
propA: '데이터 A'
}
};
},
methods: {
// 컴포넌트와 props 동적 변경
changeComponent(component, props) {
this.currentComponent = component;
this.currentProps = props;
}
},
components: {
Component1,
Component2
}
}
</script>
- 장점: 여러 컴포넌트를 동적으로 전환하고, 각 컴포넌트에 다른
props
를 동적으로 전달할 수 있음. - 단점: 상태가 유지되지 않고, 전환될 때 새로운 인스턴스가 생성됨. 이를 방지하기 위해
keep-alive
를 사용해야 함. - 사용 시기: 동적으로 여러 컴포넌트를 전환해야 하고, 각 컴포넌트에 다른 데이터(
props
)를 전달할 때 적합합니다. 예를 들어 탭 전환 시 각 탭에 서로 다른 데이터를 보여줄 때 유용합니다.
💻 4. keep-alive
: 상태를 유지한 채 컴포넌트 캐싱
keep-alive
는 캐싱된 컴포넌트의 상태를 유지하도록 도와줍니다. 동적으로 컴포넌트를 전환할 때, 컴포넌트가 초기화되지 않고 이전 상태를 유지해야 한다면 keep-alive
를 사용하면 됩니다. 컴포넌트를 전환해도 메모리에 캐싱된 상태로 유지되기 때문에 성능 최적화에도 도움이 됩니다.
📄 keep-alive
와 props
동적 전달 예시 코드
<template>
<div>
<button @click="changeComponent('Component1', { propA: '데이터 A' })">컴포넌트 1</button>
<button @click="changeComponent('Component2', { propB: '데이터 B' })">컴포넌트 2</button>
<!-- keep-alive로 상태 유지 -->
<keep-alive>
<component :is="currentComponent" v-bind="currentProps" />
</keep-alive>
</div>
</template>
<script>
import Component1 from './Component1.vue';
import Component2 from './Component2.vue';
export default {
data() {
return {
currentComponent: 'Component1',
currentProps: {
propA: '데이터 A'
}
};
},
methods: {
changeComponent(component, props) {
this.currentComponent = component;
this.currentProps = props;
}
},
components: {
Component1,
Component2
}
}
</script>
- 장점: 상태를 유지하면서 동적 컴포넌트를 전환하고, 각 컴포넌트에 다른
props
를 넘길 수 있음. - 단점: 컴포넌트를 메모리에 캐싱하므로, 많은 컴포넌트를 캐싱할 경우 메모리 사용량 증가 가능.
- 사용 시기: 상태 유지가 필요하면서도 동적 컴포넌트 전환이 필요한 상황에서 사용. 예를 들어, 동적 페이지 전환 시 각 페이지의 입력 상태나 폼 데이터를 그대로 유지하고 싶을 때 적합합니다.
💻 5. 동적 컴포넌트 전환 시 $emit
메서드도 동적으로 변경하기
동적으로 컴포넌트를 전환할 때, 이벤트($emit
)를 통해 상위 컴포넌트에 데이터를 전달해야 할 때가 많습니다. 이때 컴포넌트에 따라 이벤트 메서드도 동적으로 변경할 필요가 있습니다. 컴포넌트를 전환하면서 해당 컴포넌트에서 발생하는 이벤트를 동적으로 처리할 수 있도록 설정할 수 있습니다.
📄 동적 컴포넌트에서 이벤트 처리 예시
<template>
<div>
<button @click="currentComponent = 'Component1'">컴포넌트 1</button>
<button @click="currentComponent = 'Component2'">컴포넌트 2</button>
<component :is="currentComponent" @custom-event="handleEvent" />
</div>
</template>
<script>
import Component1 from './Component1.vue';
import Component2 from './Component2.vue';
export default {
data() {
return {
currentComponent: 'Component1'
};
},
methods: {
handleEvent(data) {
// 이벤트에 따라 처리할 동작을 설정
if (this.currentComponent === 'Component1') {
console.log('Component1 이벤트:', data);
} else if (this.currentComponent === 'Component2') {
console.log('Component2 이벤트:', data);
}
}
},
components: {
Component1,
Component2
}
}
</script>
- 동적으로 변경된 컴포넌트에서 발생하는 이벤트를 동적으로 처리할 수 있습니다.
- 상위 컴포넌트에서는 동일한 이벤트 리스너를 사용하되, 컴포넌트에 따라 다른 동작을 수행할 수 있습니다.
💻 6. v-if, v-show, :is, keep-alive 차이점 요약
특징 | v-if | v-show | :is | keep-alive |
렌더링 동작 | 조건에 따라 컴포넌트를 DOM에서 제거 | 컴포넌트를 DOM에 유지, CSS로 숨김 | 동적으로 컴포넌트를 교체 | 상태를 유지하면서 컴포넌트를 캐싱 |
상태 유지 여부 | 컴포넌트가 제거되면 상태 초기화 | 상태가 유지됨 | 상태가 유지되지 않음 (keep-alive 필요) | 상태 유지됨 |
DOM 제거 여부 | 컴포넌트가 DOM에서 완전히 제거됨 | 컴포넌트는 DOM에 남아 있음 | 컴포넌트가 동적으로 전환됨 | 컴포넌트가 메모리에 남아 있음 |
성능 | 자주 변경 시 성능 저하 가능성 있음 | 성능에 유리 | 성능에 유리, keep-alive로 상태 유지 필요 | 성능 최적화, 메모리 사용량 증가 가능 |
사용 목적 | 상태가 초기화되어야 할 때 | 상태를 유지한 채 보이기/숨기기 | 여러 컴포넌트를 동적으로 전환 | 상태를 유지하면서 동적 전환할 때 |
📌 정리
v-if
: 컴포넌트를 조건에 따라 추가/제거하며, 상태가 초기화됩니다.v-show
: 상태를 유지한 채 DOM에서 컴포넌트를 숨기거나 보이기만 합니다.:is
: 여러 컴포넌트를 동적으로 전환할 수 있으며, 다른props
를 동적으로 전달할 수 있습니다. 상태가 초기화되며,keep-alive
로 상태를 유지할 수 있습니다.keep-alive
: 상태를 유지하면서 동적으로 컴포넌트를 전환할 때 사용합니다. 상태가 캐싱되며, 성능 최적화에 도움을 줍니다.- 동적 컴포넌트에서
$emit
을 통해 상위 컴포넌트로 이벤트를 전달할 때는 동적으로 변경된 컴포넌트의 이벤트를 상위 컴포넌트에서 동적으로 처리할 수 있습니다.
'WEB' 카테고리의 다른 글
[WEB] Nuxt.js와 Spring을 이용한 POI Excel 파일 업로드 및 처리 (1) | 2024.11.27 |
---|---|
[Nuxt] Nuxt 2 설치 및 실행 (0) | 2024.05.26 |
[IntelliJ]Spring boot JSP 404 ERROR (2) | 2024.02.27 |
[Vue.js] Vewx란? (1) | 2024.02.16 |
[Intellij] intellij tomcat 실행 시 한글 깨짐 (0) | 2024.01.08 |