[TIL]Vue+Typescirpt+Vuex 사용하기 -3

gun·2020년 12월 24일
0

vue+typescript+vuex

목록 보기
3/7

Vuex란?

Vuex는 Vue.js 애플리케이션에 대한 상태 관리 패턴 + 라이브러리로, React의 Flux패턴에서 아이디어를 얻어 만들었습니다.

Flux패턴이란?

MVC패턴의 문제점

페이스북에서 말하는 MVC의 가장 큰 단점은 양방향 데이터 흐름 입니다.

MVC패턴에서 Controller는 Model의 데이터를 조회하거나 업데이트 하는 역할을 합니다. Model이 업데이트 되면, View는 화면에 반영합니다. View는 Model을 업데이트 할 수도 있습니다. Model이 업데이트 되어 View가 따라서 업데이트 되고 업데이트 된View가 다시 다른 Model을 업데이트 한다면 또 다른 업데이트가 될수 있습니다. 웹,앱이 크지않고, 복잡하지 않다면 이 MVC패턴이 문제가 될게 없으나 위 사진처럼 View와 Model이 서로 많은 의존을 하게 된다면 어디서 무엇을 업데이트 했는지 추적하기가 어려울 것입니다. 이로인해 개발자가 추적하기 힘든 버그가 발생하게 됩니다.
대표적인 예로 페이스북의 알림 버그가 있었습니다. 이를 해결하기 위해 페이스북은 Flux를 도입했습니다.

Flux패턴

Flux패턴의 가장 큰 특징은 단방향 데이터 흐름입니다.
데이터 흐름은 Dispatcher -> Store -> View, View에서 데이터를 변경할 때에는 View -> Dispatcher -> store 방향으로만 단방향으로 데이터를 컨트롤 하게 됩니다.


Vuex를 사용하여 TodoList 만들기

저희가 사용하던 프로젝트에서는 이미 Vuex 라이브러리가 적용되어 있을겁니다.
먼저 저번에 사용했던 state, method를 가져와 Vuex에 적용시켜주겠습니다.

//store/index
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);
//Type을 정의해 줍니다
interface State {
  todoList: TodolistType[];
}

interface TodolistType {
  text: string;
  completed: any;
}
export default new Vuex.Store({
  state: {
    //todoList라는 State속성을 추가해 줍니다
    todoList: [
      {
        text: "test-todo1",
        completed: false,
      },
      {
        text: "test-todo2",
        completed: true,
      },
      {
        text: "test-todo3",
        completed: false,
      },
    ],
  },
  mutations: {
    //동기적으로 변환할 method를 설정해 줍니다.
    deleteTodo(state: State, index: number) {
      state.todoList.splice(index, 1);
    },
    compelete(state: State, index: number) {
      state.todoList[index].completed = !state.todoList[index].completed;
    },
    addTodo(state: State, text: string) {
      const todo = {
        text,
        completed: false,
      };
      state.todoList.push(todo);
    },
  },
  actions: {},
});

간단하게 state, mutations, action 관해 설명 해보겠 습니다.
State : Vuex는 단일 상태 트리 를 사용합니다. 즉 State는 원본역할을 합니다. 이는 애플리케이션 하나당 하나의 저장소만 갖게 된다는 것을 의미합니다.
Mutataions, Action: Vuex 저장소에서 실제로 상태를 변경하는 방법은 Mutations와 Action으로 변경하는것 입니다.그중 Mutations는 동기적으로 상태를 변경하는 것으로 인자를 받아 Vuex의 State를 변경할수 있고 computed가 아닌 Methodes에 등록한다는 점이 다릅니다. Action은 비 동기적으로 상태를 변경하는 것으로 주로 서버와 통신중 사용하게 됩니다. 각 Mutations와 Action에는 타입 문자열 핸들러와 전달 인자를 받습니다.

//HelloWorld.vue
<template>
  <el-card class="todo-container">
    <h2>Todo List</h2>
    <form>
      <el-input placeholder="Please input" v-model="input"></el-input>
      <el-button type="primary" @click="addTodo(input)">Add Todo</el-button>
    </form>
    <ul>
      <li class="todo-item" v-bind:key="index" v-for="(todo, index) in $store.state.todoList">
        <p class="text">{{ todo.text }}</p>
        <el-button
          v-if="todo.completed"
          @click="compelete(index)"
          class="complete completed"
        >Complete</el-button>
        <el-button v-else @click="compelete(index)" class="complete">Complete</el-button>
        <el-button @click="deleteTodo(index)" class="delete">Delete</el-button>
      </li>
    </ul>
  </el-card>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

interface TodosType {
  text?: string;
  completed?: boolean;
}

@Component
export default class HelloWorld extends Vue {
  input?: string = "";
  created() {
    //store는 this.$store.state로 확인할수 있습니다.
    console.log(this.$store.state, "store");
  }

  addTodo(text: string) {
    //Mutations는 반드시 this.$store.commit('mutations이름', 인자)로 지정해주어야 합니다.
    this.$store.commit("addTodo", text);
  }

  compelete(index: number) {
    this.$store.commit("compelete", index);
  }

  deleteTodo(index: number) {
    this.$store.commit("deleteTodo", index);
  }

}
</script>

마무리

이제 좀 감이 오시나요? 정리하자면 Vuex는 한개의 Store를 갖게 되고 State에 데이터를 저장할수 있습니다. Vuex의 State를 변경하기 위해서는 Mutations와 Action을 사용해 this.store.commit(Mutations,전달인자)를받아변경할수있습니다.Action같은경우는this.store.commit('Mutations이름', 전달인자)를 받아 변경할수 있습니다. Action같은 경우는 this.store.dispatch("Action이름", 전달인자)를 사용하시면 됩니다.

0개의 댓글