[Vue] - Todo Vuex

배정규·2020년 8월 23일
0

vue

목록 보기
4/7

Vuex 기본 세팅

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

Vue.use(Vuex);

export default new Vuex.Store({
  state: { // data 가 들어가는 곳
    
  },
  mutations: { // 여기서 data 를 업데이트

  },
  actions: {  // 메소드가 들어가는 곳

  },
  getters: { // computed 같은 개념

  }
})

state

  • Vue 에서 data 개념

mutations

  • mutations 를 통해서 state 를 변화시킨다.
  • 여기서 함수를 정의하고 함수 안에 state 로 접근해서 state 를 변경한다.
  • store mutations 에서 메소드를 추가했다.
export default new Vuex.Store({
  state: { // data 가 들어가는 곳
    todos: [
      { id: 1, text: "buy a car", checked: false },
      { id: 2, text: "play game", checked: false },
    ],
  },
  mutations: { // 여기서 data 를 업데이트
    ADD_TODO(state, value) { // 첫번째 인자로 state 를 가져온다. 이로인해 state 로 접근이 가능해진다.  
      state.todos.push({
        id: Math.random(),
        text: value,
        checked: false,
      });
    },
    TOGGLE_TODO(state, { id, checked }) {
      const index = state.todos.findIndex((todo) => {
        return todo.id === id;
      });
      state.todos[index].checked = checked;
    },
    DELETE_TODO(state, todoId) {
      const index = state.todos.findIndex((todo) => {
        return todo.id === todoId;
      });
      state.todos.splice(index, 1);
    }
  },
  actions: {  // 메소드가 들어가는 곳

  },
  getters: { // computed 같은 개념

  }
})
  • store 에서 정의한 메소드를 가져온다.
  • methods 안에 this.$store.commit("메소드명", value) 으로 store 메소드를 가져와서 사용한다.
  • 첫번째 인자는 store 에서 정의한 메소드, 두번째 인자는 보내줄 값
<template>
  <div>
    <input
      v-model="todoText"
      type="text"
      class="w-100 p-2"
      placeholder="Type todo"
      @keyup.enter="addTodo"
    />
  </div>
</template>

<script>
export default {
  data() {
    return {
      todoText: "",
    };
  },
  methods: {
    addTodo(e) {
      this.$store.commit("ADD_TODO", e.target.value); // 첫번째 인자로 store 에서 원하는 computed 메소드 받아옴, 두번째 인자는 보낼 value
      this.todoText = "";
    },
  },
};
</script>

<style>
</style>

actions

actions: {  // 메소드(함수)가 들어가는 곳, 비동기 작업을 하고 그 다음에 state 에 있는 date 를 변경할 때 사용
    getUsers({ commit }) {
      axios.get("https://jsonplaceholder.typicode.com/users")
        .then(res => {
          commit('SET_USERS', res.data);
        });
    },
    addTodo({ commit }, value) {
      setTimeout(function () {  // 보통 이곳에 axios.post() 가 들어간다. 
        commit('ADD_TODO', value)
      }, 500); // 2초 후에 이 함수를 실행하겠다. 비동기 작업을 setTimeout 으로 대체해봄
    },
    toggleTodo({ commit }, payload) { //payload 는 data 
      setTimeout(function () {
        commit('TOGGLE_TODO', payload);
      }, 500)
    },
    deleteTodo({ commit }, todoId) {
      setTimeout(function () {
        commit('DELETE_TODO', todoId);
      }, 500)
    }
  },

getters

  • store getters 에서 numberOfCompletedTodo 를 만들어주면 다른 컴포넌트에서 사용 가능하다.
  • 아래는 store
getters: { // computed 같은 개념
    numberOfCompletedTodo: state => {
      return state.todos.filter((todo) => todo.checked).length;
    }
  }
  • 야래는 store getters 를 사용하는 다른 컴포넌트
<template>
  <div>Completed Todo: {{ numberOfCompletedTodo }}</div>
</template>

<script>
export default {
  computed: {
    // // state 를 가져올 때는 computed 안에 코드 작성하면 된다
    // todos() {
    //   return this.$store.state.todos;
    // },
    numberOfCompletedTodo() { // 이렇게 getters 를 사용해줄 수 있다.
      return this.$store.getters.numberOfCompletedTodo;
    },
  },
};
</script>

<style>
</style>

map 헬퍼

<script>
import { mapState, mapActions } from "vuex"; //vuex 가 제공하는 maphelper 함수를 사용
export default {
  created() {
    this.getUsers();
  },
  computed: {
    ...mapState(["users"]), // 아래 6줄처럼 해줘야할 것을 이렇게 한줄로 줄여준다.
    // ...mapState({ people: "users" }), // users 대신 다른 이름을 사용하고 싶으면 오브젝트로 바꿔서 사용해주면 된다.
    // users() {
    //   return this.$store.state.users;
    // },
    // todos() {
    //   return this.$store.state.todos;
    // },
  },
  methods: {
    ...mapActions(["getUsers"]),
    // getUsers() {
    //   this.$store.dispatch("getUsers");
    // },
  },
};
</script>

Vuex Modules

  • 애플리케이션의 모든 상태가 store 에 포함될 경우 규모가 커짐에 따라 store 는 매우 커지게 될 것이다.
  • 이를 위해 Modules 를 사용하면 store 에 모여있는 방대한 코드를 모듈로 나누어 사용할 수 있다.
  • 모듈 사용 전 store 모습
import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios';

Vue.use(Vuex);

export default new Vuex.Store({
  state: { // data 가 들어가는 곳
    todos: [
      { id: 1, text: "buy a car", checked: false },
      { id: 2, text: "play game", checked: false },
    ],
    users: []
  },
  mutations: { // 여기서 data 를 업데이트
    SET_USERS(state, users) {
      state.users = users;
    },
    ADD_TODO(state, value) { // 첫번째 인자로 state 를 가져온다. 이로인해 state 로 접근이 가능해진다.  
      state.todos.push({
        id: Math.random(),
        text: value,
        checked: false,
      });
    },
    TOGGLE_TODO(state, { id, checked }) {
      const index = state.todos.findIndex((todo) => {
        return todo.id === id;
      });
      state.todos[index].checked = checked;
    },
    DELETE_TODO(state, todoId) {
      const index = state.todos.findIndex((todo) => {
        return todo.id === todoId;
      });
      state.todos.splice(index, 1);
    }
  },
  actions: {  // 메소드(함수)가 들어가는 곳, 비동기 작업을 하고 그 다음에 state 에 있는 date 를 변경할 때 사용
    getUsers({ commit }) {
      axios.get("https://jsonplaceholder.typicode.com/users")
        .then(res => {
          commit('SET_USERS', res.data);
        });
    },
    addTodo({ commit }, value) {
      setTimeout(function () {  // 보통 이곳에 axios.post() 가 들어간다. 
        commit('ADD_TODO', value)
      }, 500); // 2초 후에 이 함수를 실행하겠다. 비동기 작업을 setTimeout 으로 대체해봄
    },
    toggleTodo({ commit }, payload) { //payload 는 data 
      setTimeout(function () {
        commit('TOGGLE_TODO', payload);
      }, 500)
    },
    deleteTodo({ commit }, todoId) {
      setTimeout(function () {
        commit('DELETE_TODO', todoId);
      }, 500)
    }
  },
  getters: { // computed 같은 개념
    numberOfCompletedTodo: state => {
      return state.todos.filter((todo) => todo.checked).length;
    }
  }
})
  • 모듈 안에 state 를 불러오기 위해서는 모듈 이름을 추가해줘야 한다.
computed: {
    todos() {
      return this.$store.state.todo.todos; // state 다음에 모듈 이름인 todo 를 추가해줬다.  
    },
  },
  • 모듈 사용 후 store 모습
  • 관련된 기능을 모듈로 분리하고 store 에 import 해서 사용한다.
import Vue from 'vue';
import Vuex from 'vuex';
import todo from './modules/todo';
import user from './modules/todo';

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    todo,
    user
  }
})
profile
Seize the day

0개의 댓글