본문 바로가기
Vue/Vue 정리

< Vuex >

by 마늘아빠 2021. 1. 6.
728x90
반응형

Vue는 Data 관리가 중요하다

부모 자신 간에 이벤트를 전달할 때 emit과 prop의 발생이 복잡하게 일어나기 때문!

Vuex에서 저장소(임시저장공간)를 운영!

Vuex

Vue.js application에 대한 상태관리패턴 + 라이브러리

application의 모든 Component들의 중앙 저장소 역할(데이터관리)

상위(부모) 하위(자식)의 단계가 많이 복잡해 진다면 데이터의 전달하는 부분이 매우 매우 복잡해진다.

application이 여러 구성 요소로 구성되고 더 커지는 경우 데이터 공유 문제도 발생

Vue의 이벤트 구조

Vuex의 저장소를 이용한 구조

상태 관리 패턴

상태 (state - data) : 앱을 작동하는 원본 소스

뷰 (DOM) : 상태의 선언적 매핑

액션 (methods) : 뷰에서 사용자 입력에 대해 반응적으로 상태를 바꾸는 방법

  • 상태 관리 패턴 예시 Code
    new Vue({
    // 상태
    data(){
    	return {
    		count: 0
    	}
    },
    //뷰
    template: `<div>{}</div>,
    //액션
    methods:{
    	increment(){
    		this.count++
    	}
    }
    });

참고 : https:vuex.vuejs.org/kr

핵심 컨셉

Vuex 저장소의 개념

State : 단일 상태 트리를 사용. application마다 하나의 저장소를 관리(data)

Getters : Vue Instance의 Computed와 같은 역할. State를 기반으로 계산(Computed)

Mutations : State의 상태를 변경하는 유일한 방법(동기 methods)

Actions : 상태를 변이 시키는 대신 액션으로 변이에 대한 커밋 처리(비동기 methods)

Vuex 설정

module 시스템과 함께 사용시 Vue.use()를 통해 Vuex 설정

  • 예시 Code
    import Vue from 'vue';
    import Vuex from 'vuex';
  • 기본 Vuex Code
    export default new Vuex.Store({
      state: {
        count: 0,
      },
    });

저장소(Store) - state

저장소에서 data 속성의 역할

application에서 공유해야할 data 관리

State에 접근하는 방법

this.$store.state.data_name

저장소(Store) - Getters

component가 vuex의 state를 직접 접근하는 코드가 중복되는 경우

해결 : Store의 state를 참조하는 Getters를 활용

Vuex는 무조건 단방향

복잡한 계산식을 처리할 때 사용한다

  • 정의 및 사용 Code
    getters:{
    	countMsg(state){
    			state.count += 1;
    	}
    }
    this.$store.getters.countMsg
  • Vuex Getter 추가 Code
    methods: {
        addCount: function() {
          this.count += 1;
          this.$store.state.count++;
        }
      }
    export default new Vuex.Store({
      state: {
        count: 0,
      },
      getters: {
        // 복잡한 계산식을 처리 : computed
        countMsg(state) {
          // return state.count + '번 호출됨';
          let msg = '10번보다 ';
          if (state.count > 10) {
            msg += '많이 ';
          } else {
            msg += '적게 ';
          }
          return msg + ' 호출됨(' + state.count + ')';
        },
      },
    });

저장소(Store) - mapGetters

getters를 조금 더 간단하게 호출

주의 : Babel 관련 에러 발생시

  1. npm install —save core-js
  1. Updated file babel.config.js:

    preset :[

    [

    '@vue/app',

    {

    useBuiltlns:'entry',

    },

    ],

],

  • Vuex mapGetters 추가 Code
    computed: {
    // 메소드 여러개 등록 
      ...mapGetters(['countMsg', 'msg1', 'msg2', 'msg3']),
      total() {
        return this.$store.state.count;
      },
    export default new Vuex.Store({
      state: {
        count: 0,
      },
      getters: {
        /*아래의 형태를 간단하게 사용가능하게
        해주는것이 helper함수
          this.$store.getters.countMsg
          this.$store.gettres.msg1
          this.$store.gettres.msg2
          this.$store.gettres.msg3
        */
    
        // 복잡한 계산식을 처리 : computed
        countMsg(state) {
          // return state.count + '번 호출됨';
          let msg = '10번보다 ';
          if (state.count > 10) {
            msg += '많이 ';
          } else {
            msg += '적게 ';
          }
          return msg + ' 호출됨(' + state.count + ')';
        },
        msg1(state) {
          return 'msg1 : ' + state.count;
        },
        msg2(state) {
          return 'msg2 : ' + state.count;
        },
        msg3(state) {
          return 'msg3 : ' + state.count;
        },
      },
    });

저장소(store) - Mutations

State의 값을 변경하기 위해 사용

각 컴포넌트에서 State의 값을 직접 변경하는 것은 권장하지 않음

State의 값의 추적을 위해 동기적 기능에 사용

Mutations는 직접 호출이 불가능. store.commit('정의된이름')으로 호출가능

  • Vuex Mutations 추가 Code
    export default new Vuex.Store({
      state: {
        count: 0,
      },
      mutations: {
        ADD_ONE(state) {
          state.count += 1;
        },
        ADD_COUNT(state, num) {
          state.count += num;
        },
        ADD_OBJ_COUNT(state, payload) {
          // payload : 객체일때
          state.count += payload.num;
        },
      },
      getters: {
        // 복잡한 계산식을 처리 : computed
        countMsg(state) {
          // return state.count + '번 호출됨';
          let msg = '10번보다 ';
          if (state.count > 10) {
            msg += '많이 ';
          } else {
            msg += '적게 ';
          }
          return msg + ' 호출됨(' + state.count + ')';
        },
      },
    });

저장소(store) - Actions

비동기 작업의 결과를 적용하려고 할 때 사용

Mutations는 상태 관리를 위해 동기적 처리

비동기 처리는 Actions가 담당

Actions는 비동기 로직의 처리가 종료되면 Mutations 호출

  • 전체 호출 Code
    <template>
      <div>
        <button v-on:click="addCount">{{ title }} - {{ count }}</button>
        <button v-on:click="addTenCount">{{ title }} - {{ count }}</button>
        <button v-on:click="addObjCount">{{ title }} - {{ count }}</button>
        <button v-on:click="asyncCount">Action {{ title }} - {{ count }}</button>
      </div>
    </template>
    
    <script>
    import { mapMutations, mapActions } from 'vuex';
    export default {
      name: 'Subject',
      props: ['title'],
      data() {
        return {
          count: 0,
        };
      },
      methods: {
        ...mapMutations({
          addMOne: 'ADD_ONE',
          addMTenCount: 'ADD_TEN_COUNT',
          addMObjCount: 'ADD_OBJ_COUNT',
        }),
        ...mapActions(['asyncAddOne']),
        addCount: function() {
          this.count += 1;
          // this.$store.commit('addOne');
          this.addMOne();
        },
        addTenCount: function() {
          this.count += 10;
          // this.$store.commit('addCount', 10);
          this.addMTenCount(10);
        },
        addObjCount: function() {
          let num = Math.round(Math.random() * 100);
          this.count += num;
          // this.$store.commit('addObjCount', { num });
          this.addMObjCount({ num });
        },
        asyncCount() {
          this.asyncAddOne();
        },
      },
    };
    </script>
    
    <style></style>
  • Vuex Actions 추가 Code
    export default new Vuex.Store({
      state: {
        count: 0,
      },
      actions: {
        asyncAddOne(context) {
          setTimeout(() => {
            context.commit('ADD_ONE');
          }, 2000);
        },
      },
      mutations: {
        ADD_ONE(state) {
          state.count += 1;
        },
        ADD_TEN_COUNT(state, payload) {
          state.count += payload;
        },
        ADD_OBJ_COUNT(state, payload) {
          state.count += payload.num;
        },
      },
      getters: {
        // 복잡한 계산식을 처리 : computed
        countMsg(state) {
          // return state.count + '번 호출됨';
          let msg = '10번보다 ';
          if (state.count > 10) {
            msg += '많이 ';
          } else {
            msg += '적게 ';
          }
          return msg + ' 호출됨(' + state.count + ')';
        },
      },
    });

완성!

반응형

'Vue > Vue 정리' 카테고리의 다른 글

< Vue / Cli >  (0) 2021.01.06
< ES6 - Destructuring / LocalStorage >  (0) 2021.01.06
< Vue 정리 2 >  (0) 2021.01.06
< Vue 정리 >  (0) 2021.01.06