728x90
반응형
Todo App 리팩토링
사용 기술
ES6
Vuex
Vuex Helper
- Vuex 프로젝트 구조화와 모듈화
store.js
import Vue from "vue";
import Vuex from "vuex";
// todo Modules
import todoApp from './modules/todoApp.js'
Vue.use(Vuex);
export const store = new Vuex.Store({
modules: {
todoApp
}
});
todoApp.js
const storage = {
fetch() {
const arr = [];
if (localStorage.length > 0) {
for (let i = 0; i < localStorage.length; i++) {
if (localStorage.key(i) !== "loglevel:webpack-dev-server") {
arr.push(JSON.parse(localStorage.getItem(localStorage.key(i))));
}
}
}
return arr;
},
};
const state = {
todoItems: storage.fetch(),
};
const getters = {
storedTodoItems(state) {
return state.todoItems;
},
};
const mutations = {
addOneItem(state, todoItem) {
const obj = { completed: false, item: todoItem };
localStorage.setItem(todoItem, JSON.stringify(obj));
state.todoItems.push(obj);
},
removeOneItem(state, payload) {
localStorage.removeItem(payload.todoItem.item);
state.todoItems.splice(payload.index, 1);
},
toggleOneItem(state, payload) {
state.todoItems[payload.index].completed = !state.todoItems[payload.index]
.completed;
localStorage.removeItem(payload.todoItem.item);
localStorage.setItem(
payload.todoItem.item,
JSON.stringify(payload.todoItem)
);
},
clearAllItems(state) {
localStorage.clear();
state.todoItems = [];
},
};
export default {
state,
getters,
mutations
}
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,
TodoInput,
TodoList,
TodoFooter,
},
};
</script>
<style>
...
</style>
TodoInput.vue
<template>
<div class="inputBox shadow">
<input type="text" v-model="newTodoItem" v-on:keyup.enter="addTodo" />
<span class="addContainer" v-on:click="addTodo">
<i class="fas fa-plus addBtn"></i>
</span>
<Modal v-if="showModal" @close="showModal=false">
<h3 slot="header">
경고 !
<i class="closeModalBtn fas fa-times" @click="showModal = false"></i>
</h3>
<div slot="body">값을 입력하세요.</div>
</Modal>
</div>
</template>
<script>
import Modal from "./common/Modal.vue";
export default {
data() {
return {
newTodoItem: "",
showModal: false,
};
},
methods: {
addTodo() {
if (this.newTodoItem !== "") {
this.$store.commit("addOneItem", this.newTodoItem);
this.clearInput();
} else {
this.showModal = !this.showModal;
}
},
clearInput() {
this.newTodoItem = "";
},
},
components: {
Modal,
},
};
</script>
<style scoped>
...
</style>
TodoList.vue
<template>
<div>
<transition-group name="list" tag="ul">
<li
v-for="(todoItem, index) in this.storedTodoItems"
v-bind:key="todoItem.item"
class="shadow"
>
<i
class="checkBtn fas fa-check"
v-bind:class="{checkBtnCompleted: todoItem.completed}"
v-on:click="toggleComplete({todoItem, index})"
></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>
</transition-group>
</div>
</template>
<script>
import { mapGetters, mapMutations } from "vuex";
export default {
methods: {
...mapMutations({
removeTodo: "removeOneItem",
toggleComplete: "toggleOneItem",
}),
},
computed: {
...mapGetters(["storedTodoItems"]),
},
};
</script>
<style scoped>
...
</style>
TodoFooter.vue
<template>
<div class="clearAllContainer">
<span class="clearAllBtn" v-on:click="clearTodo">Clear All</span>
</div>
</template>
<script>
import { mapMutations } from "vuex";
export default {
methods: {
...mapMutations({
clearTodo: "clearAllItems",
}),
},
};
</script>
<style scoped>
...
</style>
728x90
반응형
'Dev > Vue.js' 카테고리의 다른 글
[Vue.js] Hacker News - 라우터 기본 (0) | 2020.09.17 |
---|---|
[Vue.js] Hacker News - 소개 및 프로젝트 설정 (0) | 2020.09.17 |
[Vue.js] Vuex - 프로젝트 구조화 및 모듈화 (0) | 2020.09.14 |
[Vue.js] Vuex - 헬퍼 함수 (0) | 2020.09.14 |
[Vue.js] Vuex - 주요 기술 요소 (0) | 2020.09.11 |
댓글