-
[Do it! Vue.js 입문] Todo List 수정기능추가 ver2VueJs공부 2024. 2. 2. 23:42반응형
오랜만에 뷰를 다시 공부할 겸 TodoList를 만들면서,
이전에 만들었던 수정기능보다 간단한 방법이 생각나서 기록으로 남긴다.
- 모든 데이터의 처리는 App.vue에서 담당하며 하위 컴포넌트들은 데이터 처리를 App.vue로 $emit() 으로 요청한다.
- todoItems에 데이터를 담을 때, Date().getTime()을 id로 관리하여 처리하도록 하였다.
- 등록시간으로 sort하여 등록순으로 리스트가 출력되도록 처리하였다.
- 샘플 소스는 페이지 하단에 기재함.
[App.vue] 수정method
- TodoList.vue에서 modifyItem 이벤트를 받으면 modifyItem 을 수행하여 변경사항을 저장한다.
- localStorage에 기존과 같은 key로 setItem할 경우 기존 값 위에 덮어씌우는 것을 이용했다.
[TodoList.vue]
- 수정모드일 때 input 태그로 변환하여 값을 수정하고 다시 연필버튼을 클릭하거나 엔터를 입력하면
App.vue로 $emit 전송
샘플 소스 :
1.[App.vue]
<template> <div id="app"> <TodoHeader/> <TodoInput @addTodo="addTodo" /> <TodoList @toggleComplete="toggleComplete" @modifyItem="modifyItem" @removeItem="removeItem" :todoItems="todoItems" /> <TodoFooter @removeAll="removeAll"/> </div> </template> <script> import TodoHeader from './components/TodoHeader.vue' import TodoFooter from './components/TodoFooter.vue' import TodoList from './components/TodoList.vue' import TodoInput from './components/TodoInput.vue' export default { name: 'app', components:{ TodoHeader,TodoFooter,TodoList,TodoInput }, data() { return { todoItems : new Array(), } }, created() { this.readData(); }, methods: { readData(){ for(let i = 0; i < localStorage.length; i++){ try{ let data = localStorage.getItem(localStorage.key(i)); let isValid = this.isValidJson(data); if(isValid){ let todoItem = JSON.parse(data); this.todoItems.push(todoItem); this.todoItems.sort((i1, i2) => i1['id'] - i2['id']); } }catch(e){ return false; } } }, addTodo(todoItem){ let obj = new Object(); obj['completed'] = false; obj['item'] = todoItem; obj['id'] = new Date().getTime(); //localStorage에 추가 localStorage.setItem(obj['id'], JSON.stringify(obj)); this.todoItems.push(obj); }, isValidJson(str){ try{ JSON.parse(str); return true; } catch(e){ return false; } }, toggleComplete(idx){ this.todoItems[idx]['completed'] = !this.todoItems[idx]['completed']; localStorage.setItem(this.todoItems[idx]['id'], JSON.stringify(this.todoItems[idx])); }, modifyItem(object){ let newTodoItem = object['newText']; let idx = object['idx']; let target = this.todoItems[idx]; target['item'] = newTodoItem; localStorage.setItem(target['id'], JSON.stringify(target)); }, removeItem(idx){ localStorage.removeItem(this.todoItems[idx]['id']); this.todoItems.splice(idx, 1); }, removeAll(){ localStorage.clear(); this.todoItems = new Array(); } } } </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>
2. [TodoList.vue]
<template> <div> <TransitionGroup name="list" tag="ul"> <li v-for="(todoItem, idx) in todoItems" :key="idx" class="shadow"> <input v-if="isModify && modifIdx === idx" type="text" v-model="modifyText" @keyup.enter="toggleInputMode(todoItem, idx)" placeholder="수정할 내용을 입력하세요." /> <div v-else> <span class="chkBtn"> <i class="fa-solid fa-check" @click="toggleComplete(idx)"></i> </span> <span :class="{textCompleted : todoItem['completed']}"> {{ todoItem['item'] }} </span> </div> <span class="btnGroup"> <i class="fa-solid fa-pencil modifyBtn" @click="toggleInputMode(todoItem, idx)"/> <i class="fa-solid fa-trash removeBtn" @click="removeItem(idx)"></i> </span> </li> </TransitionGroup> </div> </template> <script> export default { data() { return { isModify : false, modifIdx : 0, modifyText : "", } }, props:{ todoItems : Array }, methods: { toggleInputMode(todoItem, idx){ this.isModify = !this.isModify; this.modifIdx = idx; if(this.isModify){ this.modifyText = todoItem['item']; } else { this.$emit('modifyItem', {'newText' : this.modifyText, 'idx':idx}); } }, toggleComplete(idx){ this.$emit('toggleComplete', idx); }, removeItem(idx){ this.$emit('removeItem', idx); } }, } </script> <style> 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; padding: 0 0.9rem; background:white; border-radius: 5px; } .chkBtn { line-height: 45px; color: #62acde; margin-right: 5px; } .chkBtnCompleted { color: #b3adad; } .textCompleted { text-decoration: line-through; color: #b3adad; } .btnGroup { margin-left: auto; } .btnGroup .removeBtn { color: #de4343; } .btnGroup .modifyBtn { color: #43de84; margin-right: 5px; } input { border-style: none; } .list-enter-active, .list-leave-active { /* transition: opacity 1s ease; */ transition: opacity 1s; } /* .list-enter-from, */ .list-enter, .list-leave-to { opacity: 0; transform: translateX(30px); } </style>
반응형'VueJs공부' 카테고리의 다른 글
Vue SpringBoot 연동하기 (0) 2024.01.21 Doit Vue.js입문 todolist 수정기능 추가하기 (0) 2022.02.12