[TIL]Vue+Typescirpt+Vuex 사용하기 -6 (Router,getters)

gun·2020년 12월 30일
1

vue+typescript+vuex

목록 보기
6/7
post-thumbnail

Vue Router란?

라우터란?

웹 페이지간의 이동방법을 뜻합니다.
싱글 페이지 애플리케이션(SPA)에서 많이 사용(React, Vue, Angulur)
브라우저에서 웹 페이지를 요청하면 서버에서 응답을 받아 사용자에게 답해주는 시간 동안 화면 상에 깜빡거리는 현상이 나타나는데, 이 부분을 라우팅을 처리한다면 화면 깜빡임 없이 매끄럽게 전환할수 있으며 사용자에게 더 빠르게 화면을 보여줄수 있습니다.


Router 사용하기

여태껏 했던 TodoList위에 Home과 About의 라우터가 있습니다.


무엇을?

이 Router의 About에 compelted가 True인 완료한 목록만 보이게 설정해 보겠습니다.

먼저 views에 Completed.vue를 만들어 다음과 같이 채워주시면 됩니다.

//src/views/Completed
<template>
  <ul>
    <li class="todo-item" v-bind:key="index" v-for="(todo, index) in 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>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import { mapState, mapMutations, mapGetters } from "vuex";
@Component({
  computed: {
    ...mapState("todoList", ["todoList"]),
  },

  methods: {
    ...mapMutations({
      deleteTodo: "todoList/deleteTodo",
      compelete: "todoList/compelete"
    })
  }
})
export default class Completed extends Vue {
  beforeMount() {
    console.log(this.$store.getters["todoList/CompeleteList"]);
    // console.log(this.$store.state);
  }
}
</script>

<style scoped lang="scss">
.complete.completed {
  background-color: #409eff;
}
</style>

일단 할일 목록을 나타낼수 있게 TheListItems.vue와 똑같이 작성해 줍니다.

//src/router/index.ts
const routes: Array<RouteConfig> = [
  {
    path: "/",
    name: "Home",
    component: Home,
  },
  {
    path: "/completed",	//Router EndPoint
    name: "Completed",
    component: () =>
      import("../views/Completed.vue"),
  },
];

이제 http://localhost:8080/completed로 접속하게 되면 Completed.vue가 랜더링 되게 됩니다. 이제 버튼도 수정해 주어야 겠죠.

// src/views/App.vue
<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/completed">completed</router-link>
    </div>
    <router-view />
  </div>
</template>

이제 화면에 completed를 클릭했을 때 인풋은 없어지고 TodoList들만 뜨게 됩니다.
저희가 원하는 목표는 할일을 완료한 일들만 뜨게 하는것 입니다.
이때 getters를 이용해 주시면 됩니다.

//sr/store/Todos/todoList.ts
const getters = {	//getters추가
  CompeleteList(state: State) {
    return state.todoList.filter((x: TodolistType) => {	//todoList의 completed가 True인 값만 리턴 해줍니다.
      return x.completed;
    });
  },
};
export default {
  namespaced: true,
  state,
  mutations,
  getters,
};

다음과 같이 작성하면 getters의 CompeleteList는 todoList배열이 filter되면서 completed가 true인 값만 리턴하게 됩니다.

이제 본격적으로 컴포넌트에 적용 시켜 보겠습니다.

//src/views/Completed.vue
import { mapState, mapMutations, mapGetters } from "vuex";

@Component({
  computed: {
    ...mapState("todoList", ["todoList"]),
    ...mapGetters({					//mapGetters를 추가해줍니다.
      CompeleteList: "todoList/CompeleteList"		//getters는 computed인거 아시죠?
    })
  },

mapGetters를 작성을 완료 하시면 CompeleteList는 store에서 선언해준 필터링 된 값만 나오게 됩니다.
템플릿에 적용 해보겠습니다.

//src/views/Completed.vue

<template>
  <ul>
    <li class="todo-item" v-bind:key="index" v-for="(todo, index) in CompeleteList">	//CompeleteList로 수정
      <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>
</template>

여기 까지 하시면 getters를 통해 filter된 값이 랜더링 되게 됩니다.

한가지 의문

여기까지 순조롭게 완료 하셨다면 한가지 의문점이 생기실수도 있을거 같습니다.
저희가 성능을 위해 나눠줬던 TheListItems 컴포넌트와 똑같은 구조를 보여주고 있습니다.
이걸 보고 재 사용 하면 더 효율적이게 사용할수 있지 않을까? 라는 생각이 들면 아주 잘 하고 계신거 같습니다.
다음 게시글에서는 컴포넌트를 재 사용 해보겠습니다!

0개의 댓글