// store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export const store = new Vuex.Store({
});
// main.js
import { store } from './store/store.js';
new Vue({
...,
store,
...
});
data()templatemethods
컴포넌트 -> 비동기 로직 -> 동기 로직 -> 상태

✅ 단방향이라는 것이 중요!!
datacomputedmethodsasync methods// Vue
data: {
message: 'Hello Vue.js!'
}
// Vuex
state: {
message: 'Hello Vue.js!'
}
<!-- Vue -->
<p>{{ message }}</p>
<!-- Vuex -->
<p>{{ this.$store.state.message }}</p>
computed()처럼 미리 연산된 값을 접근하는 속성// store.js
state: {
num: 10
},
getters: {
getNum(state) {
return state.num;
},
doubleNum(state) {
return state.num * 2;
}
}
<p>{{ this.$store.getters.getNum }}</p>
<p>{{ this.$store.getters.doubleNum }}</p>
commit()으로 동작시킨다// store.js
state: { num: 10 },
mutations: {
printNum(state) {
return state.num;
},
sumNum(state, anotherNum) {
return state.num + anotherNum;
}
}
// App.vue
this.$store.commit('printNum');
this.$store.commit('sumNum', 20);
// store.js
state: { storeNum: 10 },
mutations: {
modifyState(state, payload) {
console.log(payload.str);
return state.storeNum += payload.num;
}
}
// App.vue
this.$store.commit('modifyState', {
str: 'passed from payload!!',
num: 20
});

methods: {
increaseCounter() { this.$store.state.counter++; }
}
특정 시점에 어떤 컴포넌트가 state를 접근하여 변경한 건지 확인하기 어렵기 때문
따라서, 뷰의 반응성을 거스르지 않게 명시적으로 상태 변화를 수행.
반응성, 디버깅, 테스팅 혜택
dispatch()로 동작시킨다아래는 actions에서 mutations를 사용할 때의 흐름을 확인해 볼 수 있는 코드이다
// store.js
state: {
num: 10
},
mutations: {
doubleNum(state) { // 3️⃣
return state.num * 2;
}
},
actions: {
delayDoubleNum(context) { // 2️⃣ context로 store의 메서드와 속성에 접근
context.commit('doubleNum');
}
}
// App.vue
this.$store.dispatch('delayDoubleNum'); // 1️⃣
// store.js
mutations: {
addCounter(state) {
state.counter++;
}
},
actions: {
delayedAddCounter(context) {
setTimeout(() => context.commit('addCounter'), 2000);
}
}
// App.vue
methods: {
incrementCounter() {
this.$store.dispatch('delayedAddCounter');
}
}
// store.js
mutations: {
setData(state, fetchedData) {
state.product = fetched.Data;
}
},
actions: {
fetchProductData(context) {
return axios.get('https://domain.com/products/1')
.then(response => context.commit('setData', response));
}
}
// App.vue
methods: {
getProduct() {
this.$store.dispatch('fetchProductData');
}
}

[그림] 여러 개의 컴포넌트에서 mutations로 시간 차를 두고 state를 변경하는 경우
// store.js
export const store = new Vuex.store({
state: { ... },
getters: { ... },
mutations: { ... },
actions: { ... }
});
위 코드를 모듈화 하면 아래처럼 작성할 수 있다
/// store.js
import * as getters from 'store/getters.js';
import * as mutations from 'store/mutations.js';
import * as actions from 'store/actions.js';
export const store = new Vuex.store({
state: { ... },
getters, // getters: getters,
mutations, // mutations: mutations
actions // actions: actions
});
modules 속성 사용import Vue from 'vue';
import Vuex from 'vuex';
import todo from 'modules/todo.js';
export const store = new Vuex.Store({
modules: {
moduleA: todo, // 모듈 명칭 : 모듈 파일 이름
}
});
// todo.js
const state = { ... };
const getters = { ... };
const mutations = { ... };
const actions = { ... };
// App.vue
import { mapState } from 'vuex';
import { mapGetters } from 'vuex';
import { mapMutations } from 'vuex';
import { mapActions } from 'vuex';
export default {
computed: { ...mapState(['num']), ...mapGetters(['countedNum']) },
methods: { ...mapMutations(['clickBtn']), ...mapActions(['asyncClickBtn']) }
};
// store.js
state: {
num: 10
}
// App.vue
import { mapState } from 'vuex';
computed: {
...mapState(['num'])
}
<!-- <p>{{ this.$store.state.num }}</p> -->
<p>{{ this.num }}</p>
// store.js
getters: {
reverseMessage(state) {
return state.msg.split('').reverse().join('');
}
}
// App.vue
import { mapGetters } from 'vuex';
computed: { ...mapGetters(['reverseMessage']) }
<!-- <p>{{ this.$store.getters.reverseMessage }}</p> -->
<p>{{ this.reverseMessage }}</p>
// store.js
mutations: {
clickBtn(state) {
alert(state.msg);
}
}
// App.vue
import { mapMutations } from 'vuex';
methods: {
...mapMutations(['clickBtn']),
authLogin() {},
displayTable() {}
}
<button @click="clickBtn">popup message</button>
// store.js
state: { storeNum: 10 },
mutations: {
modifyState(state, payload) {
console.log(payload.str);
return state.storeNum += payload.num;
}
}
// App.vue
import { mapMutations } from 'vuex';
methods: {
// 인자를 작성하지 않아도 호출할 때 인자가 있다면 암묵적으로 넘겨준다
...mapMutations(['modifyState'])
}
<button @click="modifyState({str, num})"></button>
// store.js
actions: {
delayClickBtn(context) {
setTimeout(() => context.commit('clickBtn'), 2000);
}
}
// App.vue
import { mapActions } from 'vuex';
methods: {
...mapActions(['delayClickBtn']),
}
<button @click="delayClickBtn">delay popup message</button>
// 배열 리터럴
...mapMutations([
'clickBtn'
])
// 객체 리터럴
...mapMutations({
popupMsg: 'clickBtn' // 컴포넌트 methods 이름 : Store의 mutations 이름
})