728x90
반응형
Todo App
간단한 일정관리 App으로 기본 CRUD를 구현하기 적합하다.
구조
<Root> <App> <TodoHeader> <TodoInput> <TodoList> <TodoFooter>
컴포넌트 생성 및 등록하기
1. src/components
에 필요한 컴포넌트용 vue파일
생성

2. App.vue에 컴포넌트용 vue파일
import
// App.vue <template> <div id="app"> <TodoHeader></TodoHeader> <TodoInput></TodoInput> <TodoList></TodoList> <TodoFooter></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 { components: { 'TodoHeader': TodoHeader, 'TodoInput': TodoInput, 'TodoList': TodoList, 'TodoFooter': TodoFooter } } </script> <style> body { text-align: center; background-color: #f6f6f6; } input { border-style: groove; width: 200px; } button { border-style: groove; } .shadow { box-shadow: 5px 10px 10px rgba(0, 0, 0, 0.03); } </style>
파비콘, 반응형 웹, 폰트, 아이콘 태그 설정하기
// index.html ... <head> <!-- 반응형 태그 --> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <!-- favicon 설정 --> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <!-- fontawesome --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.min.css"/> <!-- google font --> <link href="https://fonts.googleapis.com/css2?family=Ubuntu&display=swap" rel="stylesheet"> </head> ...
TodoHeader 구현
기능
- App 제목
// TodoHeader.vue <template> <div> <h1>TODO it!</h1> </div> </template> <style scoped> /* scoped 선언 시 해당 컴포넌트에서만 유효하다는 선언 */ h1 { color: #2F3B52; font-weight: 900; margin: 2.5rem 0 1.5rem; } </style>
TodoInput 구현
기능
- 할 일 추가 (버튼 클릭, 엔터키 이벤트)
localStorage
에 객체로 할 일, 완료여부 저장- 저장 후 입력란 비우기
// TodoInput.vue <template> <div class="inputBox shadow"> <!-- enter 입력 시 addTodo 함수 실행 --> <input type="text" v-model="newTodoItem" v-on:keyup.enter="addTodo"> <!-- 클릭 시 addTodo 함수 실행 --> <span class="addContainer" v-on:click="addTodo"> <i class="fas fa-plus addBtn"></i> </span> </div> </template> <script> export default { data: function() { return { newTodoItem: '' } }, methods: { addTodo: function() { // 입력값이 공백이 아닐 때 if(this.newTodoItem !== '') { // 완료여부, 아이템 포함 객체 var obj = {completed: false, item: this.newTodoItem}; // 저장하는 로직 수행 // logcalStorage.setItem(key, value); // JSON.stringify() 객체를 String으로 변환 localStorage.setItem(this.newTodoItem, JSON.stringify(obj)); this.clearInput(); } }, clearInput: function() { // input 값 비우기 this.newTodoItem = ''; } } } </script> <style scoped> input:focus { outline: none; } .inputBox { background: white; height: 50px; line-height: 50px; border-radius: 5px; } .inputBox input { border-style: none; font-size: 0.9rem; } .addContainer { float: right; background: linear-gradient(to right, #6478fb, #8763fb); display: block; width: 3rem; border-radius: 0 5px 5px 0; } .addBtn { color: white; vertical-align: middle; } </style>
LocalStorage 확인

TodoList 구현
기능
localStorage
에 저장된 할 일 목록 표시- 체크 클릭 시 완료여부 변경
- 휴지통 클릭 시 할 일 삭제 (
localStorage
와 화면 스크립트 둘 다)
// TodoList.vue <template> <div> <ul> <!-- v-for 사용 시 v-bind:key 사용하지 않아도 무방(VSCode에서는 에러문구 출력) --> <li v-for="(todoItem, index) in todoItems" v-bind:key="todoItem.item" class="shadow"> <!-- v-bind:class="{checkBtnCompleted: todoItem.completed}"는 todoItem.completed의 true/false에 따라 동적으로 class 추가/삭제 기능 --> <i class="checkBtn fas fa-check" v-bind:class="{checkBtnCompleted: todoItem.completed}" v-on:click="toggleComplete(todoItem)"></i> <span v-bind:class="{textCompleted: todoItem.completed}">{{ todoItem.item }}</span> <span class="removeBtn" v-on:click="removeTodo(todoItem, index)"> <i class="fas fa-trash"></i> </span> </li> </ul> </div> </template> <script> export default { data: function() { return { todoItems: [] } }, methods: { removeTodo: function(todoItem, index) { // localStorage에 저장된 값 지우기 // localStorage.removeItem(key); localStorage.removeItem(todoItem); // localStroage영역만 지우는게 아니라 화면 스크립트 영역도 지워야 한다 // splice(배열의 변경을 시작할 인덱스, 배열에서 제거할 요소의 수, [배열에 추가할 요소]) this.todoItems.splice(index, 1); }, toggleComplete: function(todoItem) { // completed 변경 todoItem.completed = !todoItem.completed; // localStorage에 update가 없기 때문에 // 기존걸 지우고 localStorage.removeItem(todoItem.item); // 변경된 정보로 다시 저장 localStorage.setItem(todoItem.item, JSON.stringify(todoItem)); } }, // 뷰 라이프사이클 설정 created: function() { // localStorage에 저장된 값 꺼내 todoItems에 넣기 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)))); } } } } } </script> <style scoped> ul { list-style-type: none; padding-left: 0px; margin-top: 0; text-align: left; } li { display: flex; min-height: 50px; height: 50px; line-height: 50px; margin: 0.5rem 0; padding: 0 0.9rem; background: white; border-radius: 5px; } .removeBtn { margin-left: auto; color: #de4343; } .checkBtn { line-height: 45px; color: #62acde; margin-right: 5px; } .checkBtnCompleted { color: #b3adad; } .textCompleted { text-decoration: line-through; color: #b3adad; } </style>
TodoFooter 구현
기능
localStorage
에 저장된 할 일 전체 제거
// TodoFooter.vue <template> <div class="clearAllContainer"> <span class="clearAllBtn" v-on:click="clearTodo">Clear All</span> </div> </template> <script> export default { methods: { clearTodo: function() { // localStorage 비우기 localStorage.clear(); } } } </script> <style scoped> .clearAllContainer { width: 8.5rem; height: 50px; line-height: 50px; background-color: white; border-radius: 5px; margin: 0 auto; } .clearAllBtn { color: #e20303; display: block; } </style>
완료 화면

728x90
반응형
'Dev > Vue.js' 카테고리의 다른 글
[Vue.js] Todo App 사용자 경험 개선하기 (0) | 2020.09.10 |
---|---|
[Vue.js] Todo App 개선하기 (0) | 2020.09.10 |
[Vue.js] 싱글 파일 컴포넌트 (0) | 2020.09.09 |
[Vue.js] Vue CLI (0) | 2020.09.09 |
[Vue.js] 템플릿 문법 - 실전 (0) | 2020.09.08 |
댓글