728x90
    
    
  반응형
    
    
    
  Todo App 리팩토링
사용 기술
ES6VuexVuex 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 | 
댓글