| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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
- toggle
- SFC
- localStorage
- Server
- go
- component
- Vue
- CDN
- Matrix
- channel
- map
- 행렬
- reactivity
- Refactoring
- Dictionary
- websocket
- PROPS
- graceful shutdown
- emit
- TODO
- todo-list
- method
- container
- URL
- goroutine
- cli
- golang
- App.vue
- goroutines
- Vue.js
Archives
- Today
- Total
ksundev 님의 블로그
[TODO App][Refactoring] App 컴포넌트를 컨테이너로 만들기 4 본문
할일 전체 초기화 기능 구현하기
이번 포스트에서는 할 일 목록을 전체적으로 초기화하는 기능을 구현해보겠습니다. 특히 Vue.js에서 자식 컴포넌트가 부모 컴포넌트의 데이터를 변경하는 방법과 이벤트 기반 통신 패턴에 대해 알아보겠습니다.
1. 현재 상황과 해결해야 할 문제
컴포넌트 구조 개선: UI와 비즈니스 로직 분리
이전 포스트들과 마찬가지로, 이번에도 컴포넌트의 책임을 명확히 분리했습니다:
- TodoFooter 컴포넌트: UI 구현만 담당 (프레젠테이션 컴포넌트)
- App 컴포넌트: 비즈니스 로직과 데이터 관리 담당 (컨테이너 컴포넌트)
이러한 분리를 통해 코드의 재사용성과 유지보수성을 크게 향상시킬 수 있습니다.
현재 TodoFooter 컴포넌트의 상태
현재 TodoFooter.vue는 프레젠테이션 컴포넌트로 구현되어 있으며, "전체 초기화" 버튼을 통해 모든 할 일을 삭제하는 기능을 제공합니다. 하지만 실제 데이터 삭제 로직은 App 컴포넌트에서 처리합니다.
해결해야 할 문제
- 전체 초기화 버튼 클릭 시 모든 할 일 삭제
- localStorage에서 모든 데이터 제거
- UI에서 할 일 목록 완전히 비우기
2. TodoFooter 컴포넌트 구현
TodoFooter.vue 구조
<template>
<div class="clearAllContainer">
<span class="clearAllBtn" @click="clearTodo">전체 초기화</span>
</div>
</template>
<script>
export default {
methods: {
clearTodo() {
this.$emit("clearTodo");
},
},
};
</script>
프레젠테이션 컴포넌트로서의 역할
TodoFooter는 다음과 같은 UI 관련 책임만 가집니다:
- 버튼 렌더링: "전체 초기화" 버튼 표시
- 클릭 이벤트 처리: 사용자 클릭 시 이벤트 발생
- 스타일링: 버튼의 시각적 표현
실제 데이터 삭제 로직은 부모 컴포넌트에 위임합니다.
이벤트 발생 구조 분석
// 자식 컴포넌트에서 부모에게 이벤트 발생
methods: {
clearTodo() {
this.$emit("clearTodo"); // 커스텀 이벤트 발생
},
}
3. App 컴포넌트에서 이벤트 처리
App.vue에서 clearAllItems 메서드 구현
<template>
<div id="app">
<TodoHeader />
<TodoInput @addTodo="addOneItem" />
<TodoList
:todoItems="todoItems"
@removeItem="removeOneItem"
@toggleComplete="toggleOneItem"
/>
<TodoFooter @clearTodo="clearAllItems" />
</div>
</template>
<script>
export default {
// ... 기존 코드 ...
methods: {
// ... 기존 메서드들 ...
clearAllItems() {
localStorage.clear();
this.todoItems = [];
},
},
};
</script>
컨테이너 컴포넌트로서의 역할
App 컴포넌트는 다음과 같은 비즈니스 로직을 담당합니다:
- 데이터 관리: todoItems 배열 상태 관리
- localStorage 동기화: 브라우저 저장소와 데이터 동기화
- 이벤트 처리: 자식 컴포넌트로부터 받은 이벤트 처리
clearAllItems 메서드 분석
clearAllItems() {
localStorage.clear(); // 브라우저 저장소 완전 삭제
this.todoItems = []; // 반응형 데이터 초기화
}
4. 이벤트 기반 통신 패턴
부모-자식 컴포넌트 통신 원리
자식 컴포넌트 (TodoFooter) - UI 담당
↓ $emit("clearTodo")
부모 컴포넌트 (App) - 비즈니스 로직 담당
↓ @clearTodo="clearAllItems"
메서드 실행 및 데이터 변경Props Down, Events Up 패턴
Vue.js에서는 다음과 같은 단방향 데이터 흐름을 권장합니다:
- Props Down: 부모에서 자식으로 데이터 전달
- Events Up: 자식에서 부모로 이벤트 발생
// Props Down 예시
<TodoList :todoItems="todoItems" />
// Events Up 예시
<TodoFooter @clearTodo="clearAllItems" />
5. localStorage와 반응형 데이터 동기화
데이터 초기화 과정
clearAllItems() {
// 1. 브라우저 저장소 완전 삭제
localStorage.clear();
// 2. Vue 반응형 데이터 초기화
this.todoItems = [];
}
왜 두 단계로 나누어 처리하는가?
- localStorage.clear(): 브라우저에 저장된 영구 데이터 삭제
- this.todoItems = []: Vue의 반응형 시스템이 감지하여 UI 업데이트
6. 실제 동작 과정
전체 초기화 플로우
1. 사용자 액션: "전체 초기화" 버튼 클릭
↓
2. 이벤트 발생: TodoFooter에서 clearTodo 이벤트 발생
↓
3. 메서드 호출: App 컴포넌트의 clearAllItems 메서드 실행
↓
4. 데이터 삭제: localStorage에서 모든 데이터 제거
↓
5. 상태 초기화: todoItems 배열을 빈 배열로 설정
↓
6. UI 업데이트: Vue의 반응형 시스템이 자동으로 화면 업데이트시각적 결과
- 할 일 목록이 완전히 비워짐
- 체크박스와 텍스트가 모두 사라짐
- 앱이 초기 상태로 돌아감
7. 컴포넌트 책임 분리
TodoFooter의 책임 (프레젠테이션 컴포넌트)
// UI 구현만 담당
export default {
methods: {
clearTodo() {
// 데이터 변경 로직은 부모에게 위임
this.$emit("clearTodo");
},
},
};
App 컴포넌트의 책임 (컨테이너 컴포넌트)
// 비즈니스 로직과 데이터 관리 담당
methods: {
clearAllItems() {
// 실제 데이터 변경 로직
localStorage.clear();
this.todoItems = [];
},
}
8. 결론
이번 포스트에서는 Vue.js의 이벤트 기반 통신 패턴을 활용하여 전체 초기화 기능을 구현했습니다.
핵심 학습 포인트
- 컴포넌트 책임 분리: UI와 비즈니스 로직의 명확한 분리
- 이벤트 기반 통신:
$emit을 통한 자식→부모 통신 - 단방향 데이터 흐름: Props Down, Events Up 패턴
- localStorage 동기화: 브라우저 저장소와 Vue 상태의 일관성 유지
완성된 Todo 앱의 기능
- ✅ 할 일 추가
- ✅ 할 일 삭제
- ✅ 할 일 완료 상태 토글
- ✅ 전체 초기화
이제 완전히 동작하는 Todo 앱이 완성되었습니다! 다음 포스트에서는 복습하는 의미에서 퀴즈 몇가지만 풀어볼까요?
'[개발] Vue.js > 중급' 카테고리의 다른 글
| [TODO App] Modal 기능 구현 - Slot과 내장 Transition 활용 (4) | 2025.07.09 |
|---|---|
| [Vue][퀴즈] 10문제 (0) | 2025.07.09 |
| [TODO App][Refactoring] App 컴포넌트를 컨테이너로 만들기 3 (2) | 2025.07.07 |
| [TODO App][Refactoring] App 컴포넌트를 컨테이너로 만들기 2 (0) | 2025.07.07 |
| [TODO App][Refactoring] App 컴포넌트를 컨테이너로 만들기 1 (0) | 2025.07.07 |