티스토리 뷰

지난번 시간엔 Vuex를 이용하기 위해 개발환경을 만드는 작업까지 했었다.  Vuex에서 공부할 내용은 아래와 같다.

  • State(상태)
  • Getters
  • Mutations(변이)
  • Actions
  • Modules

이 다섯가지 중 오늘은 그 첫번째 State에 대해서 배워보도록 하겠다.

State는 말 그대로 상태를 저장하는 Vue에서는 data 와 같은 역할이라고 생각하면 편하다. 이 쯤되서 공부하기 싫은 사람들은 이렇게 생각할 수 있다.

"그러면 Vue의 data를 사용하면 되지 왜 귀찮게 Vuex를 쓰는건가?"

 

첫번째 이야기에서 내가 어플리케이션은 전역적으로 저장해야하고 사용할 정보를 제어해야하는 기능이 필요한데 그것이 Vuex가 제공해준다고 소개를 했었다. "전역적"으로 어떻게 사용할 수 있는지 컴포넌트를 하나 만들어서 확인해보도록하자.

 

지난 포스트에서 작성한 코드에서 "components" 디렉토리에 hello.vue 파일을 만들어 컴포넌트를 만들어보자.

 

 

hello.vue 파일에는 아래와 같이 코딩하자.

<template>
    <div>
        <h1>Hello, World!</h1>
        <p>
            {{msg}}
        </p>
    </div>
</template>
<script>
export default {
    name: 'HelloWorld'
    , props: {
        msg: String
    }
}
</script>

그리고 App.vue 파일은 아래와 같이 수정하자.

<template>
  <div id="app">
    <HelloWorld msg="안녕"></HelloWorld>
    <button v-on:click="onBtnClick">클릭</button>
  </div>
</template>

<script>
import Vue from 'vue'
import Vuex from 'vuex'
import HelloWorld from './components/hello'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

export default {
  name: 'app'
  , store
  , components: {
      HelloWorld
  }, methods: {
      onBtnClick: function(){
          store.commit('increment');
          console.log( store.state.count );
      }
  }
}
</script>

컴포넌트를 만들고 default에 components에 HelloWorld를 추가하여 화면에 HelloWorld 컴포넌트를 넣을 수 있도록 준비하고 teamplate에 HelloWorld 태그를 넣어서 컴포넌트를 적용한다. 그러면 이런 화면을 볼 수 있을 거다.

이제 hello.vue 에서 store를 사용할 수 있도록 아래와 같이 코드를 수정하자

<template>
    <div>
        <h1>Hello, World!</h1>
        <p>
            {{count}}
        </p>
    </div>
</template>
<script>
export default {
    name: 'HelloWorld'
    , props: {
        msg: String
    }, computed: {
        count () {
            return this.$store.state.count
        } 
    }
}
</script>

App.vue 에 미리 Vue.use(Vuex) 를 실행하여 Vuex를 사용하겠다고 미리 선언해둔 상태에서 Vue를 인스턴스화 할 때 store 객체를 전달하면 전역적으로 $store 객체로 Vuex를 활용할 수 있게 된다. 다시 설명하면 App.vue의 모든 자식 컴포넌트에 store를 주입(Inject)하여 어떤 컴포넌트던지 Store 객체에 접근 할 수 있게 된다는 이야기다.

 

위의 수정된 코드를 실행해 보면 아래처럼 버튼을 클릭할 때 마다 카운트가 올라가는 것을 확인할 수 있다.

버튼을 클릭해 실질적으로 카운트를 올리는 부분은 App.vue 에서 해주지만 실제로 UI에서 보여주는 것을 HelloWorld 컴포넌트에서 보여주고 있다. 이렇듯 Vuex는 이렇게 컴포넌트 상호간에 상태를 공유하고 이것을 UI와 모델간 바인딩 할 수 있도록 해준다.

 

Vuex를 사용하는 이유와 state를 사용하는 방법 초급 단계가 마무리 되었다. 이제 mapState와 Vue 인스턴스의 data 값을 서로 엮어서 활용하는 법에 대해서 알아보도록하자.

 

mapState는 Vuex에 정의된 state 값을 보다 심플하게 사용하기 위해서 미리 값을 매핑(?) 해놓은 거라고 생각하면 편하다. 아래의 코드를 보자.(hello.vue 파일의 코드다.)

 

<template>
    <div>
        <h1>Hello, World!</h1>
        <p>
            {{count}}
        </p>
    </div>
</template>
<script>
import { mapState } from 'vuex';

export default {
    name: 'HelloWorld'
    , props: {
        msg: String
    }, computed: mapState([
        "count"
    ])
}
</script>

이렇게 mapState를 사용하면 알아서 store 객체의 state값에서 count 값을 매핑해준다. 값을 편리하게 바인딩 할 수 있게 해준다.

 

그렇다면 아래처럼 객체를 전개하여 표시할 수도 있다.(hello.vue)

<template>
    <div>
        <h1>Hello, World!</h1>
        <p>
            {{countAlias}}
        </p>
    </div>
</template>
<script>
import { mapState } from 'vuex';

export default {
    name: 'HelloWorld'
    , props: {
        msg: String
    },computed: mapState({
        countAlias: 'count'
    })
}
</script>

위처럼 문자열 배열을 사용하지 않고 객체로 값을 매핑할 수 있다.

또 아래처럼 로컬에 있는 data 값을 활용 할 수도 있다.

 

<template>
    <div>
        <h1>Hello, World!</h1>
        <p>
            {{counter}}
        </p>
    </div>
</template>
<script>
import { mapState } from 'vuex';

export default {
    name: 'HelloWorld'
    , props: {
        msg: String
    }, data() {
        return {
            localCounter: 10
        }
    }, computed: mapState({
        counter(state){
            return state.count + this.localCounter
        }
    })
}
</script>

mapState를 통해서 메서드를 정의하면 파라미터로 state 가 넘어오게 되는데 이를 통해 로컬에 정의 한 data 값과 함께 값을 연산할 수 있다. 

 

오늘은 Vuex의 첫번째 관문 state(상태)에 대해 배워봤다. 코드가 이리저리 복잡하지만 몇번 연습하다보면 금새 적응 할 수 있을거라고 믿자. 나도 적응이 힘들다. 어쩔 땐 객체로 어쩔 땐 함수로 동작을 하는데 이게 무슨 이야기인지 조금 고민하면서 공부할 필요가 있어보인다.

 

아무튼 조금 더 힘내고 다음엔 Vuex의 세번째 이야기 Getters에 대해서 알아보는 시간을 갖기로 하고

오늘은 이만.

 

댓글
댓글쓰기 폼