본문 바로가기
Programming/Vue.js

Vue.js에서 Vuex 사용하기(2) [state, actions, mutations]

by 주리니e 2023. 1. 3.
728x90

Vue.js에서 Vuex 사용하기(2) [state, actions, mutations]

 

 

 

지난 시간에는 간단하게 Vuex를 설치하고 세팅, 선언된 값의 간단한 사용방법에 대해 알아보았다. 이번 시간에는 서버에서 데이터를 가져오는 방법(actions)과 수정 및 가공하는 방법(mutations)과 추가적으로 사용할 수 있는 방법에 대해서 알아보자. 또한 mapState와 mapMutations을 활용하여 간단하게 축약하여 사용해보자.

 

  • Axios 설치

vuex의 actions에서 ajax통신을 할 예정이므로 axios를 설치하자.

> npm install axios

 

 

  • 상태 (state)

상태(state)는 애플리케이션에서 관리되어야 할 구성요소이며 데이터이다. 이 값은 여러 컴포넌트에 의해 사용될 수 있다. 또한 컴포넌트에 의해 직접적으로 수정할 수 있으나 권고되지 않는 방식이다. 수정을 하려면 변이(mutation)을 거쳐서 수정해야 한다. 컴포넌트에 의해 직접 수정이 된다면 어느 컴포넌트에서 이 값이 수정되었는지 추적이 힘들기 때문이므로 반드시 mutations을 거쳐 수정하도록 하자. 

state() {
return {
name: "jiurinie",
age: 20,
email: "jiurinie@gmail.com",
data: {},
};
},
# HTML
<h4>안녕 {{ $store.state.name }} 나이는 {{ $store.state.age }}</h4>
# script
console.log(this.$store.state.name);

 

 

  • 변이 (mutations)

변이(mutations)은 state를 수정할 수 있는 기능을 제공하는 목적으로 만든다. 일반적인 메소드와 같으며 컴포넌트에서 호출 시 $store.commit('이름') 을 사용하여 호출한다.

mutations: {
changeName(state) {
state.name = "player1";
},
addAge(state, data) {
state.age += data;
},
showData(state, data) {
state.data = data;
},
},
# HTML
<button @click="$store.commit('changeName')">
store.js에게 이름 변경 부탁하기 버튼
</button>
# script
this.$store.commit('changeName');

 

 

  • 액션(actions)

액션은 ajax를 호출하거나 속도가 오래걸리는 경우에 사용한다. 변이(mutations)에서 ajax 통신을 해도 되지만 순차적으로 상태(state)를 변경하고 싶은 2개의 함수가 있는 경우에는 순차적 실행을 보장할 수 없는 경우가 생기기 때문이다. 액션 후 상태의 변경은 반드시 변이(mutations)에서 해야 한다. 액션에서 커밋을 쓸때에는 context라는 파라미터를 관습적으로 사용한다.

actions: {
getData(context) {
axios.get('https://jsonplaceholder.typicode.com/todos/0').then((result) => {
context.commit("showData", result.data);
});
},
},
# HTML
<p>{{ $store.state.data }}</p>
<button @click="$store.dispatch('getData')">데이터 가져오기 버튼</button>
# script
this.$store.dispatch('getData');

 

 

  • mapState, mapMutations

vuex의 mapState와 mapMutations를 이용하면 간단하게 store에 선언된 state나 mutations를 사용할 수 있다. 복잡하게 $store.state.name 등 길고 복잡하게 사용할 필요없이 컴포넌트에 선언된 데이터나 메소드처럼 사용하면 된다. 

<template>
<div>
<h4>'mapState를 활용한 데이터 가져오기' : 안녕 {{ name }} 나이는 {{ age }}</h4>
<button @click="addAge(10)">
mapMutations를 활용하여 store.js에게 나이 변경 부탁하기 버튼
</button>
</div>
</template>
<script>
import { mapState, mapMutations } from "vuex";
export default {
name: "App",
components: {},
computed: {
name() {
return this.$store.state.name;
},
...mapState(["age", "email"]),
},
methods: {
...mapMutations(["addAge"]),
}
};

 

 

  • App.vue
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<h4>안녕 {{ $store.state.name }} 나이는 {{ $store.state.age }}</h4>
<h4>'mapState를 활용한 데이터 가져오기' : 안녕 {{ name }} 나이는 {{ age }}</h4>
<button @click="$store.commit('changeName')">
store.js에게 이름 변경 부탁하기 버튼
</button>
<button @click="addAge(10)">
mapMutations를 활용하여 store.js에게 나이 변경 부탁하기 버튼
</button>
<p>{{ $store.state.data }}</p>
<button @click="$store.dispatch('getData')">데이터 가져오기 버튼</button>
</template>
<script>
import { mapState, mapMutations } from "vuex";
export default {
name: "App",
components: {},
computed: {
name() {
return this.$store.state.name;
},
...mapState(["age", "email"]),
},
methods: {
...mapMutations(["addAge"]),
}
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>

 

 

  • store.js
import { createStore } from "vuex";
import axios from "axios";
const store = createStore({
state() {
return {
name: "jiurinie",
age: 20,
email: "jiurinie@gmail.com",
data: {},
};
},
mutations: {
changeName(state) {
state.name = "player1";
},
addAge(state, data) {
state.age += data;
},
showData(state, data) {
state.data = data;
},
},
actions: {
getData(context) {
axios.get('https://jsonplaceholder.typicode.com/todos/0').then((result) => {
context.commit("showData", result.data);
});
},
},
});
export default store;

728x90

댓글