| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 |
Tags
- go
- graceful shutdown
- Matrix
- Vue
- TODO
- App.vue
- todo-list
- URL
- component
- channel
- Vue.js
- CDN
- Server
- 행렬
- map
- Refactoring
- cli
- toggle
- method
- emit
- websocket
- SFC
- goroutine
- reactivity
- container
- localStorage
- Dictionary
- goroutines
- golang
- PROPS
Archives
- Today
- Total
ksundev 님의 블로그
[TODO App] 동적 앱 만들기 (TodoList.vue) 본문
Vue.js 동적 앱 만들기 - TodoList 컴포넌트 구현
저번 포스트인 TodoInput.vue에 이어서 이번 포스트에서는 Todo(할일)를 나타낼 리스트를 완성해보겠습니다.
1. data()에 할 일 목록을 저장할 배열 정의하기
TodoList 컴포넌트에서는 여러 개의 할 일을 관리해야 하므로 배열을 사용합니다.
export default {
data() {
return {
todoItems: [], // 할 일 목록을 저장할 배열
};
},
// ... 나머지 코드
};
todoItems 배열의 역할
- 할 일 목록 저장: 여러 개의 Todo 객체를 배열 형태로 관리합니다
- 동적 렌더링: 배열의 각 요소를 화면에 동적으로 표시합니다
- 상태 관리: 할 일의 추가, 삭제, 완료 상태 변경을 추적합니다
2. created() 생명주기 훅으로 초기 데이터 로드하기
컴포넌트가 생성될 때 localStorage에서 기존 데이터를 불러와야 합니다.
참고로 loglevel:webpack-dev-server는 자동생성되는 관련없는 항목이므로 제외해줍니다.
created() {
if (localStorage.length > 0) {
for (var i = 0; i < localStorage.length; i++) {
if (localStorage.key(i) !== "loglevel:webpack-dev-server") {
this.todoItems.push(
JSON.parse(localStorage.getItem(localStorage.key(i)))
);
}
}
}
},
created() 훅의 역할
- 컴포넌트 생성 시점: DOM이 생성되기 전에 실행되어 초기 데이터를 준비합니다
- localStorage 접근: 브라우저 저장소에서 기존 할 일 데이터를 가져옵니다
- 데이터 변환: JSON 문자열을 JavaScript 객체로 변환하여 배열에 추가합니다
localStorage 데이터 로드 과정
- 저장소 확인:
localStorage.length > 0으로 데이터가 있는지 확인 - 반복 접근:
for루프로 localStorage의 모든 키에 접근 - 필터링: webpack 개발 서버 관련 키는 제외
- 데이터 파싱:
JSON.parse()로 문자열을 객체로 변환 - 배열 추가:
push()메서드로todoItems배열에 추가
3. v-for 디렉티브로 할 일 목록 렌더링하기
배열의 각 요소를 화면에 동적으로 표시하기 위해 v-for를 사용합니다.
<template>
<div>
<ul>
<li v-for="(todoItem, index) in todoItems" :key="index" class="shadow">
<i
class="checkBtn fa-solid fa-check"
:class="{ checkBtnCompleted: todoItem.completed }"
@click="toggleComplete(todoItem, index)"
></i>
<span :class="{ textCompleted: todoItem.completed }">{{
todoItem.item
}}</span>
<span class="removeBtn" @click="removeTodo(todoItem, index)">
<i class="fa-solid fa-trash-can"></i>
</span>
</li>
</ul>
</div>
</template>
v-for 디렉티브 분석
v-for="(todoItem, index) in todoItems" :key="index"
- 반복 렌더링:
todoItems배열의 각 요소에 대해<li>요소를 생성합니다 - 매개변수:
todoItem은 현재 할 일 객체,index는 배열의 인덱스입니다 - key 속성: Vue가 각 요소를 고유하게 식별할 수 있도록 인덱스를 키로 사용합니다
동적 클래스 바인딩
:class="{ checkBtnCompleted: todoItem.completed }"
:class="{ textCompleted: todoItem.completed }"
- 조건부 스타일링:
todoItem.completed값에 따라 클래스를 동적으로 적용합니다 - 완료 상태 표시: 할 일이 완료되면 시각적으로 다른 스타일을 적용합니다
4. methods에 할 일 관리 기능 구현하기
할 일의 완료 상태 변경과 삭제 기능을 구현합니다.
methods: {
removeTodo(todoItem, index) {
localStorage.removeItem(todoItem.item);
this.todoItems.splice(index, 1);
},
toggleComplete(todoItem, index) {
todoItem.completed = !todoItem.completed;
},
},
removeTodo() 메서드 분석
removeTodo(todoItem, index) {
localStorage.removeItem(todoItem.item);
this.todoItems.splice(index, 1);
}
1) localStorage에서 삭제
- 키 기반 삭제:
todoItem.item을 키로 사용하여 localStorage에서 해당 항목을 삭제합니다 - 영구 제거: 브라우저를 새로고침해도 삭제된 항목은 복구되지 않습니다
2) 배열에서 제거
- splice() 메서드:
index위치에서 1개의 요소를 제거합니다 - UI 자동 업데이트: 배열이 변경되면 Vue가 자동으로 화면을 다시 렌더링합니다
toggleComplete() 메서드 분석
toggleComplete(todoItem, index) {
todoItem.completed = !todoItem.completed;
}
1) 상태 토글
- 논리 부정:
!todoItem.completed로 현재 상태의 반대값으로 변경합니다 - 반응형 업데이트: 객체 속성이 변경되면 Vue가 자동으로 관련 UI를 업데이트합니다
2) 시각적 피드백
- 동적 클래스:
completed값에 따라 체크 아이콘과 텍스트 스타일이 변경됩니다 - 사용자 경험: 완료된 할 일은 시각적으로 구분되어 표시됩니다
5. 이벤트 핸들링과 매개변수 전달
템플릿에서 메서드를 호출할 때 필요한 데이터를 전달합니다.
@click="toggleComplete(todoItem, index)"
@click="removeTodo(todoItem, index)"
매개변수 전달의 중요성
- todoItem: 현재 처리할 할 일 객체 (완료 상태, 내용 등 포함)
- index: 배열에서의 위치 (삭제 시 정확한 위치 지정)
- 고유 식별: 각 할 일을 개별적으로 처리할 수 있게 합니다
6. 전체 데이터 흐름 이해하기
- 초기 로드:
created()훅에서 localStorage의 모든 할 일을todoItems배열에 로드 - 화면 렌더링:
v-for로 배열의 각 요소를<li>요소로 변환하여 표시 - 완료 토글: 체크 아이콘 클릭 시
toggleComplete()로completed상태 변경 - 항목 삭제: 휴지통 아이콘 클릭 시
removeTodo()로 localStorage와 배열에서 제거 - 자동 업데이트: 데이터 변경 시 Vue의 반응형 시스템이 자동으로 UI 업데이트
7. 완성된 TodoList.vue 컴포넌트
<template>
<div>
<ul>
<li v-for="(todoItem, index) in todoItems" :key="index" class="shadow">
<i
class="checkBtn fa-solid fa-check"
:class="{ checkBtnCompleted: todoItem.completed }"
@click="toggleComplete(todoItem, index)"
></i>
<span :class="{ textCompleted: todoItem.completed }">{{
todoItem.item
}}</span>
<span class="removeBtn" @click="removeTodo(todoItem, index)">
<i class="fa-solid fa-trash-can"></i>
</span>
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
todoItems: [],
};
},
created() {
if (localStorage.length > 0) {
for (var i = 0; i < localStorage.length; i++) {
if (localStorage.key(i) !== "loglevel:webpack-dev-server") {
this.todoItems.push(
JSON.parse(localStorage.getItem(localStorage.key(i)))
);
}
}
}
},
methods: {
removeTodo(todoItem, index) {
localStorage.removeItem(todoItem.item);
this.todoItems.splice(index, 1);
},
toggleComplete(todoItem, index) {
todoItem.completed = !todoItem.completed;
},
},
};
</script>
이제 TodoList 컴포넌트가 완성되었습니다! 저장된 할 일들을 화면에 표시하고, 완료 상태를 토글하며, 필요 없는 항목을 삭제할 수 있는 완전히 동작하는 할 일 목록이 되었습니다.
다음 포스트에서는 Todo 목록을 전체 삭제하는 TodoFooter 컴포넌트를 구현하여 완전한 Todo 앱을 완성해보겠습니다!
'[개발] Vue.js > 중급' 카테고리의 다른 글
| [TODO App][Refactoring] 현재 앱의 문제점 (1) | 2025.07.07 |
|---|---|
| [TODO App] 동적 앱 만들기 (TodoFooter.vue) (0) | 2025.07.06 |
| [TODO App] 동적 앱 만들기 (TodoInput.vue) (2) | 2025.07.06 |
| [TODO App] 각 컴포넌트 CSS 꾸미기 (0) | 2025.07.03 |
| [TODO App] 프로젝트 생성 및 앱 구조 설계 (2) | 2025.07.02 |