반응형

Vuex를 사용하여 To-Do 리스트 애플리케이션을 리팩토링하는 방법을 설명하겠습니다.

Vuex는 Vue.js 애플리케이션에서 상태 관리를 중앙에서 처리할 수 있도록 도와주는 라이브러리입니다.

이 예제에서는 Vuex를 사용하여 할 일 목록(todos)을 중앙에서 관리하고, 컴포넌트들이 Vuex 스토어를 통해 상태를 접근하고 수정하도록 하겠습니다.

 

1. Vuex 설치

 

먼저 Vuex를 설치해야 합니다.

npm install vuex@next

2. Vuex 스토어 설정 (store/index.js)

 

src/store/index.js 파일을 생성하고, Vuex 스토어를 설정합니다.

import { createStore } from 'vuex'

const store = createStore({
  state: {
    todos: []
  },
  mutations: {
    setTodos(state, todos) {
      state.todos = todos;
    },
    addTodo(state, todo) {
      state.todos.push(todo);
    },
    removeTodo(state, index) {
      if (index >= 0 && index < state.todos.length) {
        state.todos.splice(index, 1);
      }
    },
    updateTodoStatus(state, { index, completed }) {
      if (index >= 0 && index < state.todos.length) {
        state.todos[index].completed = completed;
      }
    }
  },
  actions: {
    loadTodos({ commit }) {
      const savedTodos = localStorage.getItem('todos');
      if (savedTodos) {
        commit('setTodos', JSON.parse(savedTodos));
      }
    },
    saveTodos({ state }) {
      localStorage.setItem('todos', JSON.stringify(state.todos));
    },
    addTodo({ commit, dispatch }, todoText) {
      const newTodo = { text: todoText, completed: false };
      commit('addTodo', newTodo);
      dispatch('saveTodos');
    },
    removeTodo({ commit, dispatch }, index) {
      commit('removeTodo', index);
      dispatch('saveTodos');
    },
    toggleTodoStatus({ commit, dispatch }, payload) {
      const { index, completed } = payload;
      console.log('toggleTodoStatus', index, completed);
      commit('updateTodoStatus', { index, completed });
      dispatch('saveTodos');
    }
  },
  getters: {
    todos(state) {
      return state.todos;
    }
  }
});

export default store;

3. Vue 애플리케이션에 Vuex 추가 (main.js)

 

main.js 파일에서 Vuex 스토어를 Vue 애플리케이션에 추가합니다.

import { createApp } from 'vue'
import App from './App.vue'
import vuetify from './plugins/vuetify'
import { loadFonts } from './plugins/webfontloader'
import router from './router'  // Vue Router를 추가
import store from './store'  // Vuex 스토어를 가져옵니다.


loadFonts()

createApp(App)
  .use(vuetify)
  .use(router)  // Vue Router 사용
  .use(store)  // Vuex 스토어를 사용합니다.
  .mount('#app')

4. ToDoList.vue 컴포넌트 수정

 

이제 ToDoList.vue 컴포넌트를 수정하여 Vuex 스토어에서 상태를 가져오고, 할 일을 추가 및 삭제하는 기능을 구현합니다.

<template>
  <v-container>
    <v-row>
      <v-col>
        <h1>Vue.js To-Do App</h1>
        <AddTodo @add-todo="addTodo" />
        <v-list>
          <v-list-item
            v-for="(todo, index) in todos"
            :key="index"
            @click="$router.push({ name: 'ToDoDetail', params: { id: index } })"
          >
            <template v-slot:prepend>
              <v-checkbox
                v-model="todo.completed"
                @click.stop="toggleTodoStatus({ index, completed: !todo.completed })"
                hide-details
              />
            </template>
            
            <v-list-item-title>{{ todo.text }}</v-list-item-title>
            
            <template v-slot:append>
              <v-btn icon="mdi-delete" size="small" @click.stop="removeTodo(index)">
              </v-btn>
            </template>
          </v-list-item>
        </v-list>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
import AddTodo from './AddTodo.vue'
import { mapActions, mapGetters } from 'vuex'

export default {
  name: 'ToDoList',
  components: { AddTodo },
  computed: {
    ...mapGetters(['todos'])  // Vuex에서 todos 상태를 가져옵니다.
  },
  methods: {
    ...mapActions(['addTodo', 'removeTodo', 'toggleTodoStatus']),  // Vuex 액션들을 가져옵니다.
  },
  created() {
    this.$store.dispatch('loadTodos')  // Vuex 스토어에서 할 일을 로드합니다.
  }
}
</script>

5. TodoDetail.vue 컴포넌트 수정

 

TodoDetail.vue에서 Vuex 상태를 사용하도록 수정합니다.

<template>
    <v-container>
      <h2>To-Do Detail</h2>
      <v-card>
        <v-card-text>
          <p>ID: {{ id }}</p>
          <p v-if="todo">Text: {{ todo.text }}</p>
          <p v-else>Todo not found</p>
        </v-card-text>
      </v-card>
      <v-btn @click="$router.push('/')">Back</v-btn>
    </v-container>
  </template>
  
  <script>
  import { mapGetters } from 'vuex'
  
  export default {
    props: {
      id: {
        type: String,
        required: true
      }
    },
    computed: {
      ...mapGetters(['todos']),
      todo() {
        return this.todos[this.id]
      }
    }
  }
  </script>

 

1. Vuex 상태 관리:

state: todos 배열을 중앙에서 관리합니다.

mutations: 상태를 직접적으로 변경하는 로직을 포함합니다(addTodo, removeTodo, updateTodoStatus).

actions: 비동기 작업이나 여러 변형을 처리하고, 상태를 변경하는 메서드를 포함합니다(loadTodos, saveTodos 등).

2. ToDoList.vue 컴포넌트:

computed: mapGetters를 통해 Vuex에서 todos 상태를 가져옵니다.

methods: mapActions를 통해 Vuex 액션을 사용하여 할 일을 추가, 삭제, 상태를 변경하고, 로컬 스토리지와 동기화합니다.

created: 컴포넌트가 생성될 때 loadTodos 액션을 호출하여 로컬 스토리지에서 저장된 할 일 목록을 불러옵니다.


이전 블로그

vue to-do 리스트 구현 5 - router 구현

https://juntcom.tistory.com/321 

반응형

'프론트엔드 > Vuejs' 카테고리의 다른 글

Vuetify 문서 레퍼런스 가이드  (0) 2024.08.17
vue vuex 란  (0) 2024.08.17
Vue Router란?  (0) 2024.08.17
vue to-do 리스트 구현 5 - router 구현  (0) 2024.08.17
vue to-do 리스트 구현 4 - vuetify 적용  (0) 2024.08.16

+ Recent posts