반응형
5장: 조건부 렌더링 - 상황에 맞는 UI 보여주기
조건부 렌더링은 특정 조건에 따라 다른 엘리먼트나 컴포넌트를 렌더링하는 기법입니다. Vue에서는 v-if, v-else-if, v-else, v-show 디렉티브를 사용하여 이를 구현합니다.
1. 핵심 개념 및 기법
v-if,v-else-if,v-else:v-if는 디렉티브의 표현식이true일 때만 블록을 렌더링합니다.v-else-if는 이전v-if또는v-else-if블록이false일 때 자신의 조건을 검사합니다.v-else는 앞선 모든v-if,v-else-if조건이false일 때 렌더링됩니다.- 이 디렉티브들은 "실제" 조건부 렌더링입니다. 조건이
false이면 해당 엘리먼트와 그 안의 자식 컴포넌트들은 DOM에서 완전히 제거되고 파괴됩니다.
<template>과v-if:- 여러 엘리먼트를 하나의 조건부 블록으로 묶고 싶을 때, 보이지 않는 래퍼(wrapper) 역할을 하는
<template>태그에v-if를 사용할 수 있습니다.
- 여러 엘리먼트를 하나의 조건부 블록으로 묶고 싶을 때, 보이지 않는 래퍼(wrapper) 역할을 하는
v-show:v-if와 비슷하지만, 조건과 관계없이 항상 엘리먼트를 렌더링하고 DOM에 유지합니다.- 조건이
false이면 단순히 CSS의display: none;스타일을 적용하여 엘리먼트를 숨깁니다.
v-ifvsv-show:v-if: 전환 비용이 높습니다. 조건이 자주 바뀌지 않을 때 사용하는 것이 좋습니다. 런타임에 조건이true가 될 일이 거의 없다면 초기 렌더링 비용이 더 저렴합니다.v-show: 초기 렌더링 비용이 높습니다. 엘리먼트를 매우 자주 보여주거나 숨겨야 할 때 사용하는 것이 좋습니다.
2. 예제 코드
예제 1: 로그인 상태에 따른 UI 제어
사용자의 로그인 여부(isLoggedIn)에 따라 환영 메시지 또는 로그인 버튼을 보여줍니다.
<script setup>
import { ref } from 'vue';
const isLoggedIn = ref(false);
</script>
<template>
<div>
<!-- v-if와 v-else를 사용하여 조건에 따라 다른 블록을 렌더링 -->
<div v-if="isLoggedIn">
<p>환영합니다! 다시 오셨군요.</p>
<button @click="isLoggedIn = false">로그아웃</button>
</div>
<div v-else>
<p>로그인이 필요합니다.</p>
<button @click="isLoggedIn = true">로그인</button>
</div>
</div>
</template>
예제 2: v-show로 토글하기
v-show를 사용하여 엘리먼트를 간단히 보여주거나 숨깁니다.
<script setup>
import { ref } from 'vue';
const isVisible = ref(true);
</script>
<template>
<div>
<button @click="isVisible = !isVisible">토글</button>
<!-- isVisible 값에 따라 display: none; 스타일이 적용되거나 해제됨 -->
<h1 v-show="isVisible">이 제목을 보여주거나 숨깁니다.</h1>
</div>
</template>
3. 연습 문제
문제 1: 로딩 스피너 구현하기
- 요구사항: 데이터 로딩 상태를 시뮬레이션하는
DataLoader.vue컴포넌트를 만드세요. - 세부사항:
isLoading이라는ref상태를 만들고 초기값은true로 설정합니다.onMounted훅과setTimeout을 사용하여, 컴포넌트가 마운트되고 2초 후에isLoading상태를false로 변경합니다.isLoading이true이면 "로딩 중..." 이라는 텍스트를 보여줍니다. (v-if사용)isLoading이false이면 "데이터 로딩 완료!" 라는 텍스트와 함께 가상의 데이터 목록(예:<ul><li>항목 1</li>...</ul>)을 보여줍니다. (v-else사용)
문제 1 정답 예시
<script setup>
import { ref, onMounted } from 'vue';
const isLoading = ref(true);
onMounted(() => {
setTimeout(() => {
isLoading.value = false;
}, 2000);
});
</script>
<template>
<div>
<div v-if="isLoading">
<p>로딩 중...</p>
</div>
<div v-else>
<h1>데이터 로딩 완료!</h1>
<ul>
<li>항목 1</li>
<li>항목 2</li>
<li>항목 3</li>
</ul>
</div>
</div>
</template>
문제 2: 사용자 권한에 따른 버튼 표시하기
- 요구사항: 사용자의 역할(
role)에 따라 다른 버튼을 보여주는AdminPanel.vue컴포넌트를 만드세요. - 세부사항:
user객체를 prop으로 받습니다. 이 객체는name과role('admin'또는'guest') 속성을 가집니다.- 사용자 이름을 환영하는 메시지를 항상 표시합니다. (예: "환영합니다, [user.name]님")
user.role이'admin'일 경우에만 "관리자 대시보드" 버튼을 추가로 보여줍니다. (v-if를 사용해보세요.)
- 도전과제:
user.role에 따라'editor'역할을 추가하고,'admin'은 "관리자 대시보드",'editor'는 "글쓰기" 버튼,'guest'는 아무 버튼도 보여주지 않도록v-if,v-else-if,v-else를 모두 사용해보세요.
문제 2 정답 예시
<!-- AdminPanel.vue -->
<script setup>
defineProps({
user: Object
});
</script>
<template>
<div>
<p v-if="user">환영합니다, {{ user.name }}님</p>
<p v-else>로그인되지 않았습니다.</p>
<!-- 도전과제 포함 -->
<button v-if="user && user.role === 'admin'">관리자 대시보드</button>
<button v-else-if="user && user.role === 'editor'">글쓰기</button>
</div>
</template>
<!-- App.vue (사용 예시) -->
<script setup>
import AdminPanel from './components/AdminPanel.vue';
const adminUser = { name: '최동진', role: 'admin' };
const editorUser = { name: 'Gemini', role: 'editor' };
const guestUser = { name: 'Guest', role: 'guest' };
</script>
<template>
<AdminPanel :user="adminUser" /> <!-- 관리자 대시보드 버튼 보임 -->
<hr>
<AdminPanel :user="editorUser" /> <!-- 글쓰기 버튼 보임 -->
<hr>
<AdminPanel :user="guestUser" /> <!-- 버튼 안 보임 -->
<hr>
<AdminPanel :user="null" /> <!-- "로그인되지 않았습니다." 보임 -->
</template>
반응형
'프론트엔드 > 뷰' 카테고리의 다른 글
| [Vue] 9장: 스타일링 - 컴포넌트에 옷 입히기 (0) | 2025.09.23 |
|---|---|
| [Vue] 8장: 컴포저블과 반응성 심화 - Vue 능력 끌어올리기 (0) | 2025.09.23 |
| [Vue] 7장: 폼과 `v-model` - 사용자의 입력 받기 (0) | 2025.09.23 |
| [Vue] 6장: 리스트 렌더링 - 동적인 목록 만들기 (0) | 2025.09.23 |
| [Vue] 4장: 이벤트 핸들링 - 사용자와의 상호작용 (0) | 2025.09.23 |
| [Vue] 3장: 반응성과 생명주기 - 살아 움직이는 컴포넌트 (0) | 2025.09.23 |
| [Vue] 2장: Props - 컴포넌트에 생명 불어넣기 (2) | 2025.09.23 |
| [Vue] 1장: 템플릿과 컴포넌트 - Vue.js의 첫인상 (0) | 2025.09.23 |