Vuex 기본 세팅
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
getters: {
}
})
state
mutations
- mutations 를 통해서 state 를 변화시킨다.
- 여기서 함수를 정의하고 함수 안에 state 로 접근해서 state 를 변경한다.
- store mutations 에서 메소드를 추가했다.
export default new Vuex.Store({
state: {
todos: [
{ id: 1, text: "buy a car", checked: false },
{ id: 2, text: "play game", checked: false },
],
},
mutations: {
ADD_TODO(state, value) {
state.todos.push({
id: Math.random(),
text: value,
checked: false,
});
},
TOGGLE_TODO(state, { id, checked }) {
const index = state.todos.findIndex((todo) => {
return todo.id === id;
});
state.todos[index].checked = checked;
},
DELETE_TODO(state, todoId) {
const index = state.todos.findIndex((todo) => {
return todo.id === todoId;
});
state.todos.splice(index, 1);
}
},
actions: {
},
getters: {
}
})
- store 에서 정의한 메소드를 가져온다.
- methods 안에 this.$store.commit("메소드명", value) 으로 store 메소드를 가져와서 사용한다.
- 첫번째 인자는 store 에서 정의한 메소드, 두번째 인자는 보내줄 값
<template>
<div>
<input
v-model="todoText"
type="text"
class="w-100 p-2"
placeholder="Type todo"
@keyup.enter="addTodo"
/>
</div>
</template>
<script>
export default {
data() {
return {
todoText: "",
};
},
methods: {
addTodo(e) {
this.$store.commit("ADD_TODO", e.target.value);
this.todoText = "";
},
},
};
</script>
<style>
</style>
actions
actions: {
getUsers({ commit }) {
axios.get("https://jsonplaceholder.typicode.com/users")
.then(res => {
commit('SET_USERS', res.data);
});
},
addTodo({ commit }, value) {
setTimeout(function () {
commit('ADD_TODO', value)
}, 500);
},
toggleTodo({ commit }, payload) {
setTimeout(function () {
commit('TOGGLE_TODO', payload);
}, 500)
},
deleteTodo({ commit }, todoId) {
setTimeout(function () {
commit('DELETE_TODO', todoId);
}, 500)
}
},
getters
- store getters 에서 numberOfCompletedTodo 를 만들어주면 다른 컴포넌트에서 사용 가능하다.
- 아래는 store
getters: {
numberOfCompletedTodo: state => {
return state.todos.filter((todo) => todo.checked).length;
}
}
- 야래는 store getters 를 사용하는 다른 컴포넌트
<template>
<div>Completed Todo: {{ numberOfCompletedTodo }}</div>
</template>
<script>
export default {
computed: {
numberOfCompletedTodo() {
return this.$store.getters.numberOfCompletedTodo;
},
},
};
</script>
<style>
</style>
map 헬퍼
<script>
import { mapState, mapActions } from "vuex";
export default {
created() {
this.getUsers();
},
computed: {
...mapState(["users"]),
},
methods: {
...mapActions(["getUsers"]),
},
};
</script>
Vuex Modules
- 애플리케이션의 모든 상태가 store 에 포함될 경우 규모가 커짐에 따라 store 는 매우 커지게 될 것이다.
- 이를 위해 Modules 를 사용하면 store 에 모여있는 방대한 코드를 모듈로 나누어 사용할 수 있다.
- 모듈 사용 전 store 모습
import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
todos: [
{ id: 1, text: "buy a car", checked: false },
{ id: 2, text: "play game", checked: false },
],
users: []
},
mutations: {
SET_USERS(state, users) {
state.users = users;
},
ADD_TODO(state, value) {
state.todos.push({
id: Math.random(),
text: value,
checked: false,
});
},
TOGGLE_TODO(state, { id, checked }) {
const index = state.todos.findIndex((todo) => {
return todo.id === id;
});
state.todos[index].checked = checked;
},
DELETE_TODO(state, todoId) {
const index = state.todos.findIndex((todo) => {
return todo.id === todoId;
});
state.todos.splice(index, 1);
}
},
actions: {
getUsers({ commit }) {
axios.get("https://jsonplaceholder.typicode.com/users")
.then(res => {
commit('SET_USERS', res.data);
});
},
addTodo({ commit }, value) {
setTimeout(function () {
commit('ADD_TODO', value)
}, 500);
},
toggleTodo({ commit }, payload) {
setTimeout(function () {
commit('TOGGLE_TODO', payload);
}, 500)
},
deleteTodo({ commit }, todoId) {
setTimeout(function () {
commit('DELETE_TODO', todoId);
}, 500)
}
},
getters: {
numberOfCompletedTodo: state => {
return state.todos.filter((todo) => todo.checked).length;
}
}
})
- 모듈 안에 state 를 불러오기 위해서는 모듈 이름을 추가해줘야 한다.
computed: {
todos() {
return this.$store.state.todo.todos;
},
},
- 모듈 사용 후 store 모습
- 관련된 기능을 모듈로 분리하고 store 에 import 해서 사용한다.
import Vue from 'vue';
import Vuex from 'vuex';
import todo from './modules/todo';
import user from './modules/todo';
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
todo,
user
}
})