| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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
- TODO
- goroutines
- container
- go
- channel
- component
- Refactoring
- CDN
- graceful shutdown
- Vue
- map
- reactivity
- websocket
- PROPS
- golang
- emit
- SFC
- Dictionary
- goroutine
- Vue.js
- cli
- localStorage
- Matrix
- todo-list
- Server
- 행렬
- App.vue
- URL
- method
- toggle
Archives
- Today
- Total
ksundev 님의 블로그
[TODO App][Refactoring] App 컴포넌트를 컨테이너로 만들기 1 본문
컨테이너란?
저번 포스트에서 간단히 언급했었죠?
컨테이너라는 것은 비즈니스 로직을 관리하고, 하위 컴포넌트들에게 데이터를 전달하는 역할을 하는 컴포넌트입니다.
간단히 생각하자면 애플리케이션의 두뇌역할을 한다고 생각하면 됩니다.
컨테이너의 주요 특징
1) 데이터 관리
- 애플리케이션의 상태(state)를 중앙에서 관리
- 여러 컴포넌트가 공유하는 데이터를 보관
- 데이터의 변경과 업데이트를 담당
2) 비즈니스 로직 처리
- 복잡한 계산이나 데이터 처리 로직을 포함
- API 호출이나 외부 서비스와의 통신
- 이벤트 핸들링과 상태 변경 로직
3) 하위 컴포넌트 제어
- 자식 컴포넌트들에게 필요한 데이터를 props로 전달
- 자식 컴포넌트에서 발생한 이벤트를 처리
- 컴포넌트 간의 통신을 중재
리팩토링
1. TodoList 컴포넌트의 책임(역할) App 컴포넌트로 옮기기
현재 TodoList 컴포넌트의 책임
현재 TodoList.vue는 다음과 같은 책임을 가지고 있습니다:
- 데이터 관리:
todoItems배열을 관리 - localStorage 접근: 데이터 로드 및 저장
- 비즈니스 로직: 할 일 삭제, 완료 상태 토글
- UI 렌더링: 할 일 목록을 화면에 표시
리팩토링 목표
TodoList 컴포넌트의 데이터 관리와 비즈니스 로직을 App 컴포넌트로 옮겨서 컨테이너 패턴을 구현하겠습니다.
2. App 컴포넌트에 데이터와 메서드 추가하기
App.vue 수정
<template>
<div id="app">
<TodoHeader />
<TodoInput />
<TodoList :propsdata="todoItems" />
<TodoFooter />
</div>
</template>
<script>
import TodoHeader from "./components/TodoHeader.vue";
import TodoInput from "./components/TodoInput.vue";
import TodoList from "./components/TodoList.vue";
import TodoFooter from "./components/TodoFooter.vue";
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)))
);
}
}
}
},
components: {
TodoHeader,
TodoInput,
TodoList,
TodoFooter,
},
};
</script>
<style>
<!-- 생략 -->
</style>
주요 변경사항
1) 데이터 중앙화
data() {
return {
todoItems: [], // App 컴포넌트에서 중앙 관리
};
},
2) 생명주기 훅 이동
created() {
// localStorage에서 데이터 로드하는 로직을 App으로 이동
if (localStorage.length > 0) {
// ... 데이터 로드 로직
}
},
3. TodoList 컴포넌트를 프레젠테이션 컴포넌트로 변경
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="$emit('toggle-complete', todoItem, index)"
></i>
<span :class="{ textCompleted: todoItem.completed }">{{
todoItem.item
}}</span>
<span class="removeBtn" @click="$emit('remove-todo', todoItem, index)">
<i class="fa-solid fa-trash-can"></i>
</span>
</li>
</ul>
</div>
</template>
<script>
export default {
props: {
todoItems: {
type: Array,
required: true
}
},
// data()와 methods() 제거 - 프레젠테이션 컴포넌트로 변경
};
</script>
TodoList의 변화
1) props로 데이터 받기
props: {
todoItems: {
type: Array,
required: true
}
},
2) 책임 분리
- 이전: 데이터 관리 + UI 렌더링
- 현재: UI 렌더링만 담당
4. 컴포넌트 간 통신 구조
데이터 흐름
App 컴포넌트 (컨테이너)
├── todoItems 데이터 관리
├── localStorage 접근
├── 비즈니스 로직 처리
└── 하위 컴포넌트들과 통신
├── TodoInput ← (다음 포스트에서 다룹시다)
├── TodoList ← props로 데이터 전달, 이벤트 수신
└── TodoFooter ← (다음 포스트에서 다룹시다)이벤트 흐름
- TodoInput:
@add-todo이벤트 발생 → App의addTodo()호출 - TodoList:
@remove-todo,@toggle-complete이벤트 발생 → App의 메서드 호출 - TodoFooter:
@clear-all이벤트 발생 → App의clearAll()호출
5. 리팩토링의 장점
1) 실시간 업데이트 해결
- App 컴포넌트에서 데이터를 중앙 관리하므로 즉시 화면에 반영
- 새로운 할 일 추가 시
todoItems배열에 직접 추가되어 UI 업데이트
2) 관심사 분리
- App: 데이터 관리와 비즈니스 로직
- TodoList: UI 렌더링만 담당
3) 재사용성 향상
- TodoList는 다양한 데이터 소스와 함께 사용 가능
- 비즈니스 로직 변경 시 App 컴포넌트만 수정하면 됨
4) 테스트 용이성
- 비즈니스 로직과 UI 로직을 분리해서 테스트 가능
6. 다음 단계
이제 TodoInput과 TodoFooter 컴포넌트도 같은 방식으로 리팩토링하여 완전한 컨테이너 패턴을 구현할 수 있습니다. 이를 통해 컴포넌트 간 통신 문제를 완전히 해결하고, 더 유지보수하기 쉬운 구조를 만들 수 있을 것입니다.
'[개발] Vue.js > 중급' 카테고리의 다른 글
| [TODO App][Refactoring] App 컴포넌트를 컨테이너로 만들기 3 (2) | 2025.07.07 |
|---|---|
| [TODO App][Refactoring] App 컴포넌트를 컨테이너로 만들기 2 (0) | 2025.07.07 |
| [TODO App][Refactoring] 현재 앱의 문제점 (1) | 2025.07.07 |
| [TODO App] 동적 앱 만들기 (TodoFooter.vue) (0) | 2025.07.06 |
| [TODO App] 동적 앱 만들기 (TodoList.vue) (0) | 2025.07.06 |