본문 바로가기
Dev/Vue.js

[Vue.js] Hacker News - 스토어 구현

by dev_jsk 2020. 9. 18.
728x90
반응형

Vuex

[Vue.js] Vuex 포스팅 참고

 

설치

npm i vuex 실행

// Terminal
jskim@DESKTOP-SI6DJ17 MINGW64 /d/dev/study/vue-advanced/vue-news (master)
$ npm i vuex

구현

1. src/store/index.js 생성

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export const store = new Vuex.Store({});

2. main.jsindex.js에서 선언한 store import

import Vue from 'vue'
import App from './App.vue'

import { router } from './routers/index.js'
// store의 index.js import
import { store } from './store/index.js'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  router,
  // Vue 객체에 store 속성 추가
  // store: store
  store
}).$mount('#app')

state, actions, mutations 적용

NewsView에 기본 방식으로 적용하기

1. src/store/index.js에 NewsView에 필요한 state, actions, mutations 추가

import Vue from "vue";
import Vuex from "vuex";

import { fetchNewsList } from "../api/index.js";

Vue.use(Vuex);

export const store = new Vuex.Store({
  state: {
    news: [],
  },
  mutations: {
    SET_NEWS(state, news) {
      state.news = news;
    },
  },
  actions: {
    FETCH_NEWS(context) {
      fetchNewsList()
        .then((response) => {
          // mutations 호출
          context.commit("SET_NEWS", response.data);
        })
        .catch(function(error) {
          console.log(error);
        });
    },
  },
});

actions에서 바로 state 속성 값을 접근하여 사용하지 않고 mutations 속성 함수를 호출하는 이유는 [Vue.js] Vuex 포스팅 내 Vuex 구조와 [Vue.js] Vuex - 주요 기술 요소 포스팅 내 mutations 부분 확인

 

2. NewsView.vue 수정

<template>
  <div>
    <!-- state 속성 접근 -->
    <div v-for="user in this.$store.state.news">{{ user.title }}</div>
  </div>
</template>

<script>

export default {
  created() {
    // Vuex의 dispatch() 호출
    this.$store.dispatch("FETCH_NEWS");
  },
};
</script>

<style>
</style>

JobsView에 디스트럭처링(destructuring) 문법 사용하기

1. src/store/index.js 수정

import Vue from "vue";
import Vuex from "vuex";

import { fetchJobsList } from "../api/index.js";

Vue.use(Vuex);

export const store = new Vuex.Store({
  state: {
    jobs: [],
  },
  mutations: {
    SET_JOBS(state, jobs) {
      state.jobs = jobs;
    },
  },
  actions: {
    // destructuring
    FETCH_JOBS({ commit }) {
      fetchJobsList()
        .then(({ data }) => {
          commit("SET_JOBS", data);
        })
        .catch((error) => {
          console.log(error);
        });
    },
  },
});

2. JobsView.vue 수정

<template>
  <div>
    <div v-for="job in this.$store.state.jobs">{{ job.title }}</div>
  </div>
</template>

<script>
export default {
  created() {
    this.$store.dispatch("FETCH_JOBS");
  },
};
</script>

<style>
</style>

AskView에 Map Helper 함수 이용하기

1. src/store/index.js 수정

import Vue from "vue";
import Vuex from "vuex";

import { fetchAskList } from "../api/index.js";

Vue.use(Vuex);

export const store = new Vuex.Store({
  state: {
    ask: [],
  },
  getters: {
    fetchedAsk(state) {
      return state.ask;
    },
  },
  mutations: {
    SET_ASK(state, ask) {
      state.ask = ask;
    },
  },
  actions: {
    FETCH_ASK({ commit }) {
      fetchAskList()
        .then(({ data }) => {
          commit("SET_ASK", data);
        })
        .catch((error) => {
          console.log(error);
        });
    },
  },
});

2. AskView.vue 수정

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

<script>
import { mapState, mapGetters } from "vuex";

export default {
  computed: {
    // #3 mapGetters 사용
    ...mapGetters(["fetchedAsk"]),

    // #2 map State 사용
    // ...mapState({
    //   ask: state => state.ask
    // }),

    // #1 속성 접근 시 간단하게 하는 기본방법(map helper 함수 미사용)
    // ask() {
    //   return this.$store.state.ask;
    // }
  },
  created() {
    this.$store.dispatch("FETCH_ASK");
  },
};
</script>

<style>
</style>

store 속성 모듈화

mutations 모듈화

src/store/mutations.js 생성

export default {
  SET_NEWS(state, news) {
    state.news = news;
  },
  SET_JOBS(state, jobs) {
    state.jobs = jobs;
  },
  SET_ASK(state, ask) {
    state.ask = ask;
  },
};

actions 모듈화

src/store/actions.js 생성

// actions에서 사용할 항목 import
// src/store/index.js에서는 미사용하기 때문에 삭제
import { fetchNewsList, fetchJobsList, fetchAskList } from "../api/index.js";

export default {
  FETCH_NEWS(context) {
    fetchNewsList()
      .then((response) => {
        context.commit("SET_NEWS", response.data);
      })
      .catch((error) => {
        console.log(error);
      });
  },
  FETCH_JOBS({ commit }) {
    fetchJobsList()
      .then(({ data }) => {
        commit("SET_JOBS", data);
      })
      .catch((error) => {
        console.log(error);
      });
  },
  FETCH_ASK({ commit }) {
    fetchAskList()
      .then(({ data }) => {
        commit("SET_ASK", data);
      })
      .catch((error) => {
        console.log(error);
      });
  },
};

src/store/index.js 수정

import Vue from "vue";
import Vuex from "vuex";

// mutations, actions import
import mutations from "./mutations.js";
import actions from "./actions.js";

Vue.use(Vuex);

export const store = new Vuex.Store({
  state: {
    news: [],
    jobs: [],
    ask: [],
  },
  getters: {
    fetchedAsk(state) {
      return state.ask;
    },
  },
  mutations,
  actions,
});

 

728x90
반응형

댓글