애플리케이션이 복잡해지고 컴포넌트의 수가 많아지면 컴포넌트 간 데이터 전달이 어려워진다
💡 Vuex는 Vue.js 애플리케이션을 위한 상태관리 패턴 + 라이브러리로, 모든 컴포넌트에 대한 중앙집중식 데이터 저장소 역할을 하며 예측 가능한 방식으로 상태를 변경할 수 있다데이터를 store에 저장하고, 프로젝트 전체에서 사용할 수 있도록 해준다
npm install vuex@next --save
모든 Vuex 애플리케이션의 중심에는 store가 있다
💡 store(저장소) : 애플리케이션 상태를 저장하고 있는 컨테이너Vuex 저장소가 일반 전역 객체와 다른 점은 2가지가 있다
src/store.js
import { createStore } from "vuex";
const store = createStore({
state() {
return {
count: 0,
};
},
mutations: {
increment(state) {
state.count++;
},
},
});
export default store;
Vue 컴포넌트에서는 this.$store
로 접근이 가능하다
src/views/StoreAccess.vue
<template>
<div>
<p>Count : {{ count }}</p>
<button type="button" @click="increment">Increment</button>
</div>
</template>
<script>
export default {
computed: {
count() {
return this.$store.state.count;
},
},
methods: {
increment() {
this.$store.commit("increment");
},
},
};
</script>
this.$store.commit("increment")
: 저장소의 state에 직접 접근해서 변경하는 것이 아닌, commit을 통해서 값을 변경한다state는 프로젝트 전체에서 공통으로 사용할 변수를 정의하는 곳으로, state에 정의된 변수는 모든 컴포넌트에서 동일한 값을 사용 가능하다
state에 정의된 변수는 Vue 컴포넌트에서 computed
속성을 이용해 그 변경사항을 항상 추적할 수 있다
computed: {
count() {
return this.$store.state.count;
},
},
따로 getters
를 정의하여 값을 참조할 수도 있다(배열의 길이 등)
src/store.js
import { createStore } from "vuex";
const store = createStore({
state() {
return {
count: 0,
cart: [
{
product_id: 1,
product_name: "아이폰 거치대",
category: "A",
},
],
};
},
getters: {
cartCount: (state) => {
return state.cart.length;
},
},
mutations: {
increment(state) {
state.count++;
},
},
});
export default store;
computed: {
count() {
return this.$store.getters.cartCount;
},
},
vuex는 state에 정의된 변수를 직접 변경하는 것을 허용하지 않고, 반드시 mutations를 이용해서 변경을 해야한다
💡 mutations : state를 변경시키는 역할, 비동기가 아닌 동기 처리를 통해 state에 정의된 변수의 변경사항을 추적할 수 있게 해준다methods: {
increment() {
this.$store.commit("increment");
},
}
actions
는 mutations
와 매우 유사한 역할을 하며 action을 통해 mutations에 정의된 함수를 실행시킬 수 있다
그럼 mutations가 있는데 왜 굳이 actions를 사용할까?
actions: {
increment(context) {
// 비동기 처리 후 로직 수행 가능
context.commit("increment");
},
},
실무에서 Vuex가 쓰이는 예 중 하나로 사용자가 로그인을 하면 사용자 정보를 store에 저장하고, 여러 컴포넌트에서 가져다 쓰는 것이다
모든 컴포넌트에서는 사용자가 로그인 했는지 정보를 알 필요가 있기 때문이다
import { createStore } from "vuex";
import { persistedState } from "vuex-persistedstate";
const store = createStore({
state() {
return {
user: {},
};
},
mutations: {
user(state, data) {
state.user = data;
},
},
plugins: [
persistedState({
paths: ["user"],
}),
],
});
export default store;
출처: 고승원 저, 『Vue.js 프로젝트 투입 일주일 전』, 비제이퍼블릭(2021)