vue.js와 vue material을 이용한
간단한 todolist 앱을 만들겠습니다.
(before refactoring)
(before refactoring)
예제는 인프론의 Vue.js 끝장내기 강의를 듣고 참조하여 공부한 내용입니다.
Todolist 앱화면
구현 내용:
· header, input, list, footer component로 분리
· Things To Do라는 input 박스에 해야할일을 기입
· 해야할일 기입 후 enter 또는 오른쪽 plus버튼 클릭시, 아래 리스트에 추가
· CLEAR ALL 버튼 클릭시 전체 삭제
· refactoring 전 구현이 미완성된 상태
· vue material을 이용한 css
· localstorage를 이용한 데이터 저장/불러오기/삭제하기 기능
· header, input, list, footer component로 분리
· Things To Do라는 input 박스에 해야할일을 기입
· 해야할일 기입 후 enter 또는 오른쪽 plus버튼 클릭시, 아래 리스트에 추가
· CLEAR ALL 버튼 클릭시 전체 삭제
· refactoring 전 구현이 미완성된 상태
· vue material을 이용한 css
· localstorage를 이용한 데이터 저장/불러오기/삭제하기 기능
App.vue
<template>
<div id="app">
<TodoHeader></TodoHeader>
<TodoInput></TodoInput>
<TodoList></TodoList>
<TodoFooter></TodoFooter>
</div>
</template>
<script>
import TodoHeader from './components/TodoHeader'
import TodoInput from './components/TodoInput'
import TodoList from './components/TodoList'
import TodoFooter from './components/TodoFooter'
export default {
components: {
TodoHeader,
TodoInput,
TodoList,
TodoFooter
}
}
</script>
<style>
body {
text-align: center;
background-color: #393D49;
max-width: 800px;
width: 100%;
}
.md-layout-item {
padding: 0 5px;
}
</style>
TodoHeader.vue
<template>
<div class="header">
<span class="md-headline">Todolist</span>
</div>
</template>
<script>
export default {}
</script>
<style>
.header {
padding: 30px 0 20px;
}
</style>
TodoInput.vue
<template>
<div>
<div class="md-layout" style="margin: 0.5rem; color: #fff !important;">
<div class="md-layout-item md-size-90">
<md-field>
<label>Things To Do</label>
<!-- v-keyup:enter 아님 -->
<md-input v-model="doItem" @keyup.enter="addTodo"></md-input>
</md-field>
</div>
<div class="md-layout-item md-size-10" @click="addTodo">
<i class="fas fa-plus-circle addBtn"></i>
</div>
</div>
</div>
</template>
<script>
export default {
data: function () {
return {doItem: ''}
},
methods: {
addTodo() {
if (this.doItem) { //값이 있으면
// console.log(this.todoItem); 저장하는 로직(key, value) 객체 생성
//-> check버튼 기능 구현 위하여
var obj = {
completed: false,
item: this.doItem
};
// JOSN.stringify 자바스크립트 객체를 string으로 변환 JSON.stringify()는
// javascript 객체를 string값으로 변환시킴
// 그 이유: localstorage는 객체 출력이 안되고, string text 값만 출력됨
// localStorage.setItem(this.todoItems, this.todoItems)으로 했다가
// todoList에서 checkbox의 toggle 메소드 사용을 위해 아래로 변경
// obj라는 객체에 담아주고, 아래 localstorage value값을
// string으로 변환하여 입력
localStorage.setItem(this.doItem, JSON.stringify(obj));
this.clearInput();
}
},
clearInput() {
this.doItem = '';
}
}
}
</script>
<style>
.md-field,
.md-focused,
.md-input,
.md-textarea,
label {
background: #365FD9 !important;
border-style: none;
border-radius: 5px;
margin: 0 0 5px 0 !important;
color: #fff !important;
-webkit-text-fill-color: #ddd !important;
}
.addBtn {
vertical-align: middle;
margin-top: 12px;
font-size: 24px;
cursor: pointer;
}
</style>
Todolist.vue
<template>
<div>
<ul>
<!-- 중요 v-for instance특징, 반복문구의 index를 알려준다 -->
<!-- 클릭 remove event 위하여 todoItem, index(삭제할 해당건)를 메소드에 넘겨준다 -->
<li v-for="(todo, index) in todos" v-bind:key="todo">
<div>
<!-- todo.completed값이 true면 checkBtnCompleted class가 동작한다 -->
<i
class="fas fa-check checkBtn"
@click="toggleFn(todo, index)"
v-bind:class="{checkBtnCompleted: todo.completed}"></i>
<!-- 중요 v-bind 클래스 기존의 html 속성중 todo.completed값이 true면
textCompleted class가 동작한다 class on/off-->
<span @click="toggleFn(todo, index)"
:class="{textCompleted: todo.completed}">{{todo.item}}</span>
</div>
<!-- {{todo}}으로 출력시 { "completed": false, "item": "abcde.." } 로 나옴
-> .item 속성접근 -->
<!-- todo, index를 인자로 넣어 넘긴다 -->
<span class="removeBtn" @click="removeFn(todo, index)">
<i class="far fa-trash-alt"></i>
</span>
</li>
</ul>
</div>
</template>
<script>
export default {
data: function () {
return {
//localstorage에서 가져올 담는 공간
todos: []
}
},
//lifecycle 중 instance가 생성되자마다 호출되는 lifecycle hook
created() {
if (localStorage.length > 0) {
for (let i = 0; i < localStorage.length; i++) {
// localstorage key값을 getItem하면 value가 output됨 value가
// json.stringify(input.vue파일)에서 string type 상태
//string에서 객체형태로 변환해줘야함 json.parse();
if (localStorage.key(i) !== 'loglevel:webpack-dev-server') {
console.log(localStorage.getItem(localStorage.key(i)));
this.todos.push(JSON.parse(localStorage.getItem(localStorage.key(i))));
}
}
}
},
methods: {
removeFn(todo, index) {
//console.log(todo, index);
//localStorage.removeItem(todo); todo에 객체 전체가 들어오므로,
//화면에서는 삭제가 되어도, localstorage에서는 안없어짐
//todo.item으로 key 값을 정확하게 지울 수 있음
localStorage.removeItem(todo.item);
this.todos.splice(index, 1);
},
toggleFn(todo) {
todo.completed = !todo.completed;
//localstorage 업데이트
localStorage.removeItem(todo.item);
localStorage.setItem(todo.item, JSON.stringify(todo));
}
}
}
</script>
<style>
ul {
list-style-type: none;
padding-left: 0;
margin-top: 0;
text-align: left;
}
li {
display: flex;
min-height: 50px;
height: 50px;
line-height: 50px;
margin: 1rem;
padding: 0 0.9rem;
background: #4872F0;
border-radius: 5px;
justify-content: space-between;
}
span {
cursor: pointer;
color: #fff !important;
}
.checkBtn {
line-height: 45px;
color: #F0C148;
margin-right: 20px !important;
cursor: pointer;
}
.checkBtnCompleted {
text-decoration: line-through;
}
.textCompleted {
text-decoration: line-through;
}
.removeBtn {
cursor: pointer;
}
</style>
TodoFooter.vue
<template>
<div class="clearAllList">
<md-button class="clearAllBtn" @click="clearAll">clear all</md-button>
</div>
</template>
<script>
export default {
methods: {
clearAll() {
localStorage.clear();
}
}
}
</script>
<style>
.clearAllBtn {
background-color: #F2B705 !important;
}
</style>
반응형
'개발 > React' 카테고리의 다른 글
[vue] vue.js Post 폼 데이터 api 전송하기(axios, 유효성 검사) (0) | 2020.11.22 |
---|---|
[vue] vue.js로 todolist 투두리스트 앱 만들기(리팩토링 후) (0) | 2020.11.22 |
[vue] vue.js에서 axios 사용하여 서버 통신(vue material 테이블에 데이터 뿌리기) (0) | 2020.11.18 |
[vue] vue.js 컴포넌트 생성(컴포넌트로 쪼개기) (0) | 2020.11.15 |
[vue] vue.js 기초 정리 요약(pass props/emit event) (0) | 2020.11.10 |
댓글