[Vue3] vuex 사용, 예시
상위 컴포넌트 > 하위 컴포넌트에서 데이터 전달을 할 때는 props 로 전달을 하는데, 컴포넌트가 여러개라면 props 를 반복적으로 사용하기에 복잡하다.
props 와는 다른 방식인, 데이터를 한 곳에 저장해놓고 사용하는 방법이 있다. (규모가 큰 프로젝트에 적합)
터미널 > 새 터미널에서 다음 입력
npm install vuex@next --save
데이터를 저장해 놓을 곳인 store.js 파일 생성 (파일 명은 관례로 보통 store.js 라고 많이 작성한다.)
store.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import { createStore } from "vuex";
const store = createStore({
state() {
return {
};
},
mutations: {
},
actions: {
},
});
export default store;
|
cs |
기본 구조는 이렇다.
1. vuex 를 사용하기 위해 import 를 해준다.
4. state() : 보통의 vue 파일의 return data() 와 비슷하다. data 접근 시 사용하는 getter 와 비슷함
9. mutations : data 변경 시 사용하는 setter 와 비슷함. actions 와는 다르게 동기 방식으로 처리할 때 작성
12. actions : 서버와의 통신(ajax) 나 처리 결과를 받아올 때 같이 비동기 방식으로 처리할 때 작성
17. 다른 vue 파일에서 store.js 데이터를 사용하기 위해 export 해준다.
store.js 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
import axios from "axios";
import { createStore } from "vuex";
const store = createStore({
state() {
return {
name: "kim",
age: 20,
likes: [30, 30, 30],
clickyn: [false, false, false],
more: {},
};
},
mutations: {
이름변경(state) {
state.name = "park";
},
증가(state, payload) {
state.age += payload;
},
좋아요증가(state, i) {
state.likes[i]++;
},
클릭(state, i) {
if (state.clickyn[i] == false) {
state.likes[i]++;
} else {
state.likes[i]--;
}
state.clickyn[i] = !state.clickyn[i];
},
setMore(state, data) {
state.more = data;
},
},
actions: {
getData(context) {
axios.get("ajaxURL").then((a) => {
console.log(a.data);
context.commit("setMore", a.data);
});
},
},
});
export default store;
|
5. state() 에 여러 파일에서 접근할 데이터를 선언한다.
15. mutations() 에 데이터를 변경할 수 있는 함수들을 선언한다.
보통 매개변수 안에 (state) 라고 적어준다.
18. 파라미터가 필요한 경우 state 옆에 적어준다.
37. 서버 요청으로 받아오는 데이터 요청 함수를 선언한다.
App.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
<template>
<div>
<h4>{{ $store.state.name }}</h4>
<h4>{{ $store.state.age }}</h4>
<button @click="$store.commit('이름변경')">버튼</button>
<button @click="$store.commit('증가', 1)">증가버튼</button>
<p>{{ $store.state.more }}</p>
<button @click="$store.dispatch('getData')">더보기버튼</button>
</div>
</template>
<script>
import axios from 'axios'
import {mapMutations, mapState} from 'vuex'
export default {
name: 'App',
components: {
},
data() {
return {
}
},
methods: {
//store.js 에 있는 함수 가져다 쓰려면 ...mapMutations
//그러면 위에서 store.commit('증가') 이렇게 안쓰고 @click=증가() 이렇게 쓰면됨
...mapMutations(['이름변경', '좋아요', '증가']),
},
mounted(){
},
//computed : 페이지 로딩시 한 번만 실행 (연산 결과 저장 해 놓음)
//state 가져다 쓸때 유용함
computed : {
name(){
return this.$sotre.state.name;
},
//vuex state 한번에 꺼내쓰려면 mapState 를 쓰자
...mapState(['name','age','likes'])
}
}
</script>
|
cs |
3. store.js 의 데이터를 가져다 쓸때는 $store.state.변수명
5. store.js 의 mutations 함수를 사용할때는 $store.commit(함수명)
8. store.js 의 actions 함수를 사용할때는 $store.dispatch(함수명)
35, 39. $store.state.변수명으로 쓰기 귀찮으면 ...mapState([변수명1, 변수명2, ...]) 사용 . 15줄의 import 를 해줘야함개굴
(변수명1, 변수명2는 store.js 에 있는 변수명)
28. 위와 마찬가지로 $store.commit 쓰기 귀찮으면 ...mapMutations 사용
mapActions 도 마찬가지.
main.js
1
2
|
import store from './store.js'
app.use(store).mount('#app')
|
cs |
main.js 에 store 의 경로와 use 문을 추가해줘야 한다.