본문 바로가기
💻CODING/react. vue

[vue] vue vuex , store적용(api 통해 뉴스 사이트 구현 ver.3)

by 코딩하는 갓디노 2021. 1. 14.

 

 

오픈 API를 통하여 블로그 형식의 뉴스 사이트를 
vue.js로 구현하는 예제(ver.3)입니다. 



 

 

예제는 인프런의 캡틴판교, "장기효"님의 Vue.js 완벽 가이드 - 실습과 리팩토링으로 배우는 실전 개념을
들으면서 공부한 내용입니다.


vuex 적용

모듈화 process

No. 순서 remark
1  기본 설정   
2  state  data 속성
3  actions  api 호출, dispatch api 호출
4  mutation  state 값 변경, commit api 호출
5  화면 출력  
6  getters  리팩토링

 

컴포넌트 데이터 호출 방법

  • BEFORE: component에서 직접 api를 호출하여 사용
  • AFTER: vuex(상태관리도구)를 이용하여 vuex의 state에 api를 담아서 화면에 표시

 

vuex 설치

npm i vuex

 

store 모듈화

▶ 모듈화 전: main.js

import { router } from './routes/index.js'; 
new Vuex.Store({
  state,
  getters,
  mutations,
  actions,
})

 

 모듈화 후

 

1. 기본 설정

store 폴더 생성 후 index.js 파일 생성

import Vue from 'vue';
import Vuex from 'vuex'; 

Vue.use(Vuex);

export const store = new Vuex.Store({
  state: {},
  getters: {},
  mutations: {},
  actions: {},
})

 

2. state

· 여러 component 간의 공유되는 data 속성(=data)
· 프로젝트 레벨에 상관없이 vuex를 이용하여 하위 컴포넌트끼리 data를 공유할 수 있습니다. 

store > index.js

export const store = new Vuex.Store({
  state: {
    news: [],
  },
})

NewView.vue: 기존 data 삭제

export default {
  // data() {
  //   return {
  //     news: [],
  //   };
  // },
}

 

3. actions

· api 호출은 actions에서 선언합니다.(비동기 호출)
· 해당 component에서 dispatch라는 api를 이용하여 호출합니다. 
· actions가 backend api를 들고 와서 mutations에 넘겨주기 위한 속성입니다.
· vuex의 구조상 actions의 api data를 바로 state에 전달이 불가능하고, mutations 통하여 state에 전달합니다. 

store > index.js

import { fetchNewsList } from "../api/index"; //1. api get 코드 import

actions: {
  FETCH_NEWS() { //2. FETCH_NEWS 라는 action 이름 지정, 
    fetchNewsList()	//3. fetchNewsList와 api 코드를 담아줌
      .then(response => {
        console.log(response.data);
      })
      .catch(error => {
        console.log(error)
      })
  },
}

 

NewView.vue: 기존 api 호출 코드 삭제, action 이름을 dispatch를 이용하여 호출

created() {
  // fetchNewsList()
  //   .then((response) => (this.news = response.data))
  //   .catch((error) => console.log(error));
  this.$store.dispatch("FETCH_NEWS");
},

 

4. mutations

· action은 mutation 접근할 수 있도록 매개변수(인자)가 제공됩니다. 
· 매개변수를 commit이라는 api를 이용해서  mutation에 data를 넘깁니다. 
· 인자로 받은 결과 response.data로 state 속성 값을 변경합니다.

 매개변수.commit('mutation 이름', response.data);
 //mutation 이름에 response.data 값을 넘긴다.

 

store > index.js actions

 

actions: {
  FETCH_NEWS(context) { //매개변수 전달
    fetchNewsList()
      .then(response => {
        console.log(response.data);
        //mutation, SET_NEWS에 response.data(인자)를 넘김
        context.commit('SET_NEWS', response.data);
      })
      .catch(error => {
        console.log(error)
      })
  },
}

 

store > index.js mutations

mutations: {
  SET_NEWS(state, news) { //1st 인자: 무조건 state, 2nd 인자: response.data => news
    state.news = news
  },
},

 

5. 화면 출력

NewView.vue

<template>
  <div>
    <!-- <div v-for="item in news">{{ item.title }}</div> -->
    <!-- <div v-for="item in this.$store.state.news">{{ item.title }}</div> -->
    <div v-for="item in this.$store.state.news">
      {{ item.title }}
    </div>
  </div>
</template>

 

vuex 개발자 도구 확인 방법



 

 

6. getters: 리팩토링

· component의 computed와 동일한 속성으로 상태 값을 반환합니다.
· store에서 선언합니다.

혹시 터미널 창에서 core.js라는 문구의 에러가 뜬다면, 아래 코드를 추가 설치하세요.

yarn add core-js

 

store > index.js getters

getters: {
  fetchedAsk(state) {
    return state.ask;
  }
},

 

NewView.vue

<template>
  <div>
    <div v-for="item in askItems">
      {{ item.title }}
    </div>
  </div>
</template>

<script>
import { mapGetters } from "vuex";
export default {
  computed: {
    ...mapGetters({
      askItems: "fetchedAsk",
    }),
  }
 </script>

 

 store 속성 모듈화

효율적 관리를 위하여 state, getters, mutations, actions를 
별도의 파일에서 관리합니다. 

store 폴더 안에 actions.js 파일 생성

export default {
    SET_NEWS(state, news) {//첫번째 인자는 무조건 state, response.data = news
        state.news = news
    },
    SET_ASK(state, ask) {
        state.ask = ask
    },
    SET_JOBS(state, jobs) {
        state.jobs = jobs
    }
}

store > index.js

import actions from './actions';

export const store = new Vuex.Store({
  actions, //actions: actions,
})

 

반응형

댓글