1. store/modules/todo.js
์์ฑ
// store/modules/todo.js
import axios from '@/utils/axios';
const state = {
todos: [],
};
const getters = {
allTodos: (state) => state.todos,
};
const mutations = {
setTodos(state, todos) {
state.todos = todos;
},
addTodo(state, todo) {
state.todos.unshift(todo);
},
removeTodo(state, id) {
state.todos = state.todos.filter((t) => t.id !== id);
},
updateTodo(state, updated) {
state.todos = state.todos.map((todo) =>
todo.id === updated.id ? updated : todo
);
},
};
const actions = {
async fetchTodos({ commit }) {
const res = await axios.get('/api/todos');
commit('setTodos', res.data);
},
async addTodo({ commit }, title) {
const res = await axios.post('/api/todos', { title, completed: false });
commit('addTodo', res.data);
},
async deleteTodo({ commit }, id) {
await axios.delete(`/api/todos/${id}`);
commit('removeTodo', id);
},
async toggleTodo({ commit, state }, id) {
const target = state.todos.find((t) => t.id === id);
if (!target) return;
const updated = { ...target, completed: !target.completed };
await axios.put(`/api/todos/${id}`, { completed: updated.completed });
commit('updateTodo', updated);
},
async updateTodo({ commit }, { id, title }) {
await axios.put(`/api/todos/${id}`, { title });
commit('updateTodo', { id, title });
},
};
export default {
namespaced: true,
state,
getters,
mutations,
actions,
};
2. store/index.js
์ ๋ฑ๋ก
import Vue from 'vue';
import Vuex from 'vuex';
import auth from './modules/auth';
import theme from './modules/theme';
import todo from './modules/todo'; // โ
์ถ๊ฐ
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
auth,
theme,
todo, // โ
๋ฑ๋ก
},
});
3. TodoApp.vue
์์
<template>
<div class="todo-container">
<h2>๐งพ ํ ์ผ ๊ด๋ฆฌ (Vuex)</h2>
<div class="form">
<input v-model="newTodo" placeholder="ํ ์ผ์ ์
๋ ฅํ์ธ์" />
<button @click="handleAdd">์ถ๊ฐ</button>
</div>
<ul class="todo-list">
<TodoItem
v-for="todo in allTodos"
:key="todo.id"
:content="todo.title"
:completed="todo.completed"
:editing="editingId === todo.id"
@delete="handleDelete(todo.id)"
@edit="startEdit(todo.id)"
@update="handleUpdate(todo.id, $event)"
@toggle="handleToggle(todo.id)"
/>
</ul>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex';
import TodoItem from './TodoItem.vue';
export default {
components: { TodoItem },
data() {
return {
newTodo: '',
editingId: null,
};
},
computed: {
...mapGetters('todo', ['allTodos']),
},
mounted() {
this.fetchTodos();
},
methods: {
...mapActions('todo', [
'fetchTodos',
'addTodo',
'deleteTodo',
'updateTodo',
'toggleTodo',
]),
async handleAdd() {
if (!this.newTodo.trim()) return;
await this.addTodo(this.newTodo);
this.newTodo = '';
},
async handleDelete(id) {
await this.deleteTodo(id);
},
startEdit(id) {
this.editingId = id;
},
async handleUpdate(id, newTitle) {
if (newTitle !== null && newTitle.trim()) {
await this.updateTodo({ id, title: newTitle });
}
this.editingId = null;
},
async handleToggle(id) {
await this.toggleTodo(id);
},
},
};
</script>
์ด์ ๋ชจ๋ Todo ๊ด๋ จ ์ํ์ ๋ก์ง์ Vuex
๋ก ๊ด๋ฆฌ๋๊ณ , ์ปดํฌ๋ํธ๋ ์ค๋ก์ง ๋ฐ์ดํฐ ํํ์ ์ง์คํ ์ ์์ต๋๋ค.
FE ์ ์ฅ์
๐ฌ ๋๊ธ
โป ๋ก๊ทธ์ธ ํ ๋๊ธ์ ์์ฑํ ์ ์์ต๋๋ค.