이 문서는 “타입스크립트, AWS 서버리스로 들어올리다” 책을 기반으로 작성되었습니다.
개요 vuex
는 vue 애플리케이션 상태관리 패턴 라이브러리이다.
부모 <> 자식 간 컴포넌트 통신(props
, emit
)으로, 모든 것을 처리하기에는 힘들기 때문에 만들어졌다.
구조
용어 설명
state
: 변수 조회
getter
: 변수 조회 (computed
적 역할을 함)
action
: 변수 내용 변경, async
같은 비동기적 처리가 가능
mutation
: 변수 내용 변경, 동기적으로 이루어짐, state
는 mutate
를 통해서만 변경될 수 있다.
dispatch
: action
실행
commit
: mutate
실행
mutate
: state
변경
render
: 컴포넌트 View 수정
Example Code src/store/Counter.ts 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 import { Module, GetterTree, MutationTree, ActionTree, ActionContext } from 'vuex' ;export class Counter { public count: number = 0 ; } const getters: GetterTree<Counter, any > = { doubleCount(state: Counter): number { return state.count; }, }; const mutations: MutationTree<Counter> = { increment(state: Counter, step: number ) { state.count = state.count + step; }, } const actions: ActionTree<Counter, any > = { inc(state: ActionContext<Counter, any >, step: number ) { state.commit(`increment` , step); }, } const Counter: Module<Counter, any > = { namespaced: true , state: new Counter(), getters, mutations, actions, }; export default Counter;
src/store.ts 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import Vue from 'vue' ;import Vuex, { Module } from 'vuex' ;import Counter from './store/Counter' ; Vue.use(Vuex); const store = new Vuex.Store({ state: {}, modules: { Counter, }, }); export default store;
src/App.html (컴포넌트 - Template
부분) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <h1 > Counter</h1 > <p > {{ $store.state.Counter.count }}</p > <p > {{ $store.getters[`Counter/doubleCount`] }}</p > <p > <input type ="button" @click ="$store.commit('Counter/increment', 1)" value ="+1 증가(Mutate)" /> </p > <p > <input type ="button" @click ="$store.dispatch('Counter/inc', 2)" value </p>
vuex
는 $store
을 통해 전역 사용
state 바로 접근법 1 $store.state.Counter.count
getters 호출 1 $store.getters[`Counter/doubleCount`]
namepsaced
가 설정되어있기 때문에, <모듈이름>/<뮤테이션이름>
으로 구분한다.
commit (mutations 호출) 1 $store.commit(`Counter/increment` , {name: `Kang` , age: 26 });
commit
을 통해 mutations
호출
dispatch (actions 호출) 1 $store.dispatch(`Counter/inc` , 2 );
mapper 컴포넌트에서 vuex
가 많이 사용될 경우, 축약해서 사용할 수 있는 방법
그래도 위의 기본은 알고가자
src/App.ts 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 import Vue from 'vue' ;import Component from 'vue-class-component' ;import WithRender from './App.html' ;import { mapState, mapGetters, mapMutations, mapActions } from 'vuex' ;import './App.scss' ;@WithRender @Component ({ computed: { ...mapState({ count: (state: any ) => state.Counter.count, }), ...mapGettes({ doubleCount: `Counter/doubleCount` , }), }, methods: { ...mapMuations({ increment: `Counter/increment` , }), ...mapActions({ inc: `Counter/inc` , }), }, }) export default Class App extends Vue {}
src/App.html 1 2 3 4 5 6 7 8 9 <h2 > Mapper</h2 > <p > {{ count }}</p > <p > {{ doubleCount}}</p > <p > <input type ="button" @click ="increment(1)" value ="+1 증가(mutation)" /> </p > <p > <input type ="button" @click ="inc(2)" value ="+2 증가(action)" </p>
mapper 장단점 vuex
를 간략하게 사용할 수 있지만, 직접적인 호출이 아니기 때문에 모르는 사람이 본다면 가독성, 이해도가 떨어질 수 있다. (고인물 생성)
vue-property-decorators를 이용한 사용 설치 1 npm i vuex-module-decorators
src/store/Counter.ts 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 import { VuexModlue, Module, Mutation, Action } from 'vuex-module-decorators' ;@Module ({ namespaced: true , }) class Counter extends VuexModule { public count: number = 0 ; get doubleCount(): number { return this .count + 2 ; } @Muation public increment(step: number ) { this .count += step; } @Action public inc(step: number ) { return step; } } export default Counter;
이것 또한 데코레이터를 다 외워야 함은 있지만, mapper보다 훨씬 가독성이 뛰어난 편으로 보여 사용성이 좋아보인다.
Action
부분이 특이한데, return 값이 payload
로 자동으로 commit
으로 전달된다.
Action
내에서 다른 mutation
실행법
1 this .context.commit(`increment` , step);