조건문과 반복문
배열의 데이터를 반복 출력하는 Vue의 핵심 문법을 배웁니다.
웹 프로그램에서는 데이터의 현재 상태에 따라 화면을 다르게 표시하거나, 여러 데이터를 같은 형태로 반복해서 출력해야 하는 경우가 많습니다.
예를 들어 사원관리 프로그램에서는 사원의 재직 여부에 따라 다른 문구를 보여주고, 등록된 사원 수만큼 사원 정보를 반복해서 출력해야 합니다.
퇴사 → "퇴사" 표시
사원이 5명 → 5명의 사원정보를 반복 출력
v-if는 지정한 조건이 참일 때 HTML 요소를 화면에 표시합니다.
<script setup>
import { ref } from 'vue'
const login = ref(true)
</script>
<template>
<h2 v-if="login">
로그인되었습니다.
</h2>
</template>
현재 login 값은 true이므로 화면에는 다음 문장이 표시됩니다.
다음과 같이 값을 false로 변경하면 어떻게 될까요?
login.value = false
login = false → 화면에서 제거
단순히 글자를 안 보이게 만드는 것이 아니라 조건이 거짓이면 해당 HTML 요소가 렌더링되지 않습니다.
v-else는 바로 앞의 v-if 조건이 거짓일 때 표시할 내용을 지정합니다.
<script setup>
import { ref } from 'vue'
const login = ref(false)
</script>
<template>
<h2 v-if="login">
로그인되었습니다.
</h2>
<h2 v-else>
로그인이 필요합니다.
</h2>
</template>
JavaScript의 다음 조건문과 같은 개념입니다.
if (login) {
// 로그인 상태
} else {
// 로그아웃 상태
}
<script setup>
import { ref } from 'vue'
const login = ref(false)
function loginUser() {
login.value = true
}
function logoutUser() {
login.value = false
}
</script>
<template>
<h1>회원 시스템</h1>
<p v-if="login">
홍길동님 환영합니다.
</p>
<p v-else>
로그인이 필요합니다.
</p>
<button
v-if="!login"
@click="loginUser"
>
로그인
</button>
<button
v-else
@click="logoutUser"
>
로그아웃
</button>
</template>
로그인이 필요합니다.
[로그인]
홍길동님 환영합니다.
[로그아웃]
함수에서 직접 HTML을 수정하지 않았다는 점에 주목하세요.
login.value = true
조건이 두 개보다 많다면 v-else-if를 사용하여 여러 조건을 순서대로 검사할 수 있습니다.
<script setup>
import { ref } from 'vue'
const score = ref(85)
</script>
<template>
<p v-if="score >= 90">
A등급
</p>
<p v-else-if="score >= 80">
B등급
</p>
<p v-else-if="score >= 70">
C등급
</p>
<p v-else>
재교육 대상
</p>
</template>
score 값이 85이므로 80점 이상 조건에 해당합니다.
v-show도 조건에 따라 요소를 표시하거나 숨길 때 사용합니다.
<script setup>
import { ref } from 'vue'
const visible = ref(true)
</script>
<template>
<button @click="visible = !visible">
보이기 / 숨기기
</button>
<p v-show="visible">
사원 상세정보입니다.
</p>
</template>
버튼을 누를 때마다 visible 값이 true와 false 사이에서 변경됩니다.
두 문법 모두 조건에 따라 화면 표시 여부를 결정하지만 내부 처리 방법에는 중요한 차이가 있습니다.
| 구분 | v-if | v-show |
|---|---|---|
| 조건이 false | HTML 요소 자체를 제거 | 요소는 존재하지만 숨김 |
| 처리 방식 | 생성 / 제거 | CSS display 변경 |
| 자주 변경되는 화면 | 상대적으로 불리 | 유리 |
| 사용 예 | 로그인 여부, 권한 | 열기/닫기, 상세보기 |
v-if → 필요할 때만 화면에 만든다.
v-show → 화면에 만들어 두고 보이거나 숨긴다.
v-for는 배열에 들어 있는 여러 데이터를 같은 HTML 구조로 반복하여 출력할 때 사용합니다.
const employees = ref([ '홍길동', '김철수', '이영희' ])
Vue에서는 다음과 같이 배열을 반복할 수 있습니다.
<ul>
<li v-for="name in employees">
{{ name }}
</li>
</ul>
김철수
이영희
홍길동 → <li>홍길동</li>
김철수 → <li>김철수</li>
이영희 → <li>이영희</li>
목록에 순번이 필요하다면 v-for에서 두 번째 값인 index를 사용할 수 있습니다.
<li
v-for="(name, index) in employees"
:key="index"
>
{{ index + 1 }}. {{ name }}
</li>
2. 김철수
3. 이영희
홍길동 → index 0
김철수 → index 1
이영희 → index 2
따라서 사용자에게 1번부터 보여주려면 {{ index + 1 }}을 사용합니다.
실제 프로그램에서는 이름 하나만 저장하기보다 사원번호, 이름, 부서 등 여러 정보를 하나의 객체로 관리하는 경우가 많습니다.
const employees = ref([
{
id: 1,
name: '홍길동',
department: '개발팀'
},
{
id: 2,
name: '김철수',
department: '영업팀'
},
{
id: 3,
name: '이영희',
department: '관리팀'
}
])
이 데이터를 테이블로 출력해 보겠습니다.
<table border="1">
<tr>
<th>번호</th>
<th>이름</th>
<th>부서</th>
</tr>
<tr
v-for="emp in employees"
:key="emp.id"
>
<td>{{ emp.id }}</td>
<td>{{ emp.name }}</td>
<td>{{ emp.department }}</td>
</tr>
</table>
| 번호 | 이름 | 부서 |
|---|---|---|
| 1 | 홍길동 | 개발팀 |
| 2 | 김철수 | 영업팀 |
| 3 | 이영희 | 관리팀 |
v-for로 목록을 출력할 때는 각 항목을 구분할 수 있는 고유한 key를 지정하는 것이 좋습니다.
<tr v-for="emp in employees" :key="emp.id" >
여기에서 핵심은 다음 부분입니다.
:key="emp.id"
id = 2 → 김철수
id = 3 → 이영희
Vue는 key를 이용하여 각 데이터와 화면 요소의 관계를 구분합니다.
데이터베이스의 기본키(PK)를 사용하는 경우가 많습니다.
- employee_id
- member_id
- board_id
- product_id
:key="emp.employee_id"
이제 Vue의 반응형 데이터가 실제 화면을 어떻게 변경하는지 확인해 보겠습니다.
<script setup>
import { ref } from 'vue'
const employees = ref([
{ id: 1, name: '홍길동' },
{ id: 2, name: '김철수' }
])
function addEmployee() {
employees.value.push({
id: 3,
name: '이영희'
})
}
</script>
<template>
<h2>사원목록</h2>
<ul>
<li
v-for="emp in employees"
:key="emp.id"
>
{{ emp.id }} / {{ emp.name }}
</li>
</ul>
<button @click="addEmployee">
사원 추가
</button>
</template>
2 / 김철수
2 / 김철수
3 / 이영희
함수에서 실행한 핵심 코드는 배열에 데이터를 추가하는 코드뿐입니다.
employees.value.push({
id: 3,
name: '이영희'
})
↓
Vue가 변경 감지
↓
v-for 자동 처리
↓
화면 자동 갱신
이번에는 배열에서 특정 사원을 삭제하고 화면이 자동으로 변경되는지 확인해 보겠습니다.
<script setup>
import { ref } from 'vue'
const employees = ref([
{ id: 1, name: '홍길동' },
{ id: 2, name: '김철수' },
{ id: 3, name: '이영희' }
])
function removeEmployee(id) {
employees.value =
employees.value.filter(
emp => emp.id !== id
)
}
</script>
<template>
<h2>사원목록</h2>
<ul>
<li
v-for="emp in employees"
:key="emp.id"
>
{{ emp.name }}
<button
@click="removeEmployee(emp.id)"
>
삭제
</button>
</li>
</ul>
</template>
김철수 [삭제]
이영희 [삭제]
이영희 [삭제]
employees.value =
employees.value.filter(
emp => emp.id !== id
)
화면에서 <li> 태그를 직접 찾아 삭제하지 않습니다.
데이터만 삭제하면 Vue가 목록 화면을 자동으로 갱신합니다.
<script setup>
import { ref } from 'vue'
const name = ref('')
const employees = ref([
{ id: 1, name: '홍길동' },
{ id: 2, name: '김철수' }
])
let nextId = 3
function addEmployee() {
if (name.value === '') {
alert('이름을 입력하세요.')
return
}
employees.value.push({
id: nextId++,
name: name.value
})
name.value = ''
}
function removeEmployee(id) {
employees.value =
employees.value.filter(
emp => emp.id !== id
)
}
</script>
<template>
<h1>사원관리</h1>
<input
v-model="name"
placeholder="사원 이름"
>
<button @click="addEmployee">
추가
</button>
<hr>
<p>
전체 사원 : {{ employees.length }}명
</p>
<ul>
<li
v-for="emp in employees"
:key="emp.id"
>
{{ emp.id }}.
{{ emp.name }}
<button
@click="removeEmployee(emp.id)"
>
삭제
</button>
</li>
</ul>
</template>
[사원 이름 ] [추가]
전체 사원 : 2명
1. 홍길동 [삭제]
2. 김철수 [삭제]
입력창에 이영희를 입력한 후 추가 버튼을 누르면 새로운 객체가 배열에 추가됩니다.
1. 홍길동 [삭제]
2. 김철수 [삭제]
3. 이영희 [삭제]
이번에는 김철수를 삭제해 보겠습니다.
1. 홍길동 [삭제]
3. 이영희 [삭제]
개발자는 다음과 같이 데이터를 관리합니다.
employees.value.push(...)
employees.value = employees.value.filter(...)
데이터가 변경되면 Vue가 연결된 화면을 자동으로 갱신합니다.
│
├──→ 전체 사원 수 자동 변경
│
└──→ 사원 목록 자동 변경
개발자가 DOM 요소를 하나씩 직접 만들고 삭제하기보다 데이터의 상태를 관리하는 데 집중할 수 있습니다.
조건문과 반복문을 함께 사용하면 데이터가 존재할 때는 목록을 보여주고, 데이터가 없을 때는 안내 메시지를 표시할 수 있습니다.
<p v-if="employees.length === 0">
등록된 사원이 없습니다.
</p>
<ul v-else>
<li
v-for="emp in employees"
:key="emp.id"
>
{{ emp.name }}
</li>
</ul>
김철수
사원을 모두 삭제하면 조건이 자동으로 변경됩니다.
↓
사원 목록 표시
employees.length === 0
↓
"등록된 사원이 없습니다." 표시
Vue에서는 데이터의 현재 상태를 기준으로 화면을 구성합니다.
데이터가 변경되면 Vue가 변화를 감지하고 필요한 화면을 다시 반영하므로, 개발자는 데이터 관리와 프로그램 로직에 집중할 수 있습니다.
- v-if는 조건이 참일 때 요소를 화면에 만듭니다.
- v-else는 v-if 조건이 거짓일 때 사용합니다.
- v-else-if는 여러 조건을 순서대로 검사할 때 사용합니다.
- v-show는 요소를 유지하면서 CSS display 속성으로 표시 여부를 변경합니다.
- v-for는 배열의 데이터를 반복하여 화면에 출력합니다.
- v-for에서는 각 항목을 구분하기 위해 :key를 지정하는 것이 좋습니다.
- 객체 배열을 이용하면 사원번호, 이름, 부서 등 여러 정보를 목록으로 출력할 수 있습니다.
- 배열에 데이터를 추가하거나 삭제하면 연결된 화면도 자동으로 갱신됩니다.
- v-if와 v-for를 조합하면 데이터 유무에 따라 서로 다른 화면을 구성할 수 있습니다.
- Vue에서는 DOM을 직접 수정하기보다 데이터의 상태를 관리하는 방식으로 화면을 구성합니다.