8 두 번째 프로젝트 시작하기

source: categories/study/vue-beginner-lv5/vue-beginner-lv5_8.md

8.1 두 번째 프로젝트 오리엔테이션

  • 기존에 이미 구현된 서비스에 타입스크립트를 점진적으로 적용한다.

8.2 두 번째 프로젝트 안내

Note

git diff


yarn install && yarn serve

8.2.1 지금 현재 코드의 문제점

  1. News/Ask/Jobs 탭 메뉴를 누르면
  2. 해당 탭 메뉴의 data로 바로 바뀐 후
  3. 트랜지션(전환) 효과 발생 - 스르륵 없어졌다가 스르륵 나타나는 거
  • 그 이유
    • 현재 listItem 컴포넌트에서 storelist를 바라보는데
    • api 요청 후 받아온 데이터를 storelist에 다시 담음
    • 그런데 News/Ask/Jobs 모두 공통 listItem 쓰고있고 이게 storelist를 바라보고 있으니 list 값이 바뀌면 자동으로 화면 갱신
    • 그 후에 next() 함수 발동
    • 트랜지션(전환) 효과 발생
  • 코드 공통화를 위해 이게 깔끔하나 오히려 트랜지션(전환) 효과에선 독이된듯
    • 이를 해결할 수 있는 방법 뭐 없을까?

8.2.1.1 해결책 1. computed가 아닌 created로..

  • 이러면 데이터가 실시간으로 바뀌어도 화면에 실시간 갱신 기능은 사라진다


<template>
  <ul class="news-list">
    <li v-for="news in listItems" :key="news.id" class="post">
      <div class="points">
        {{ news.points || 0 }}
      </div>
      <div>
        <p class="news-title">
          <template v-if="news.domain">
            <a :href="news.url">{{ news.title }}</a><small class="link-text" v-if="news.domain">({{ news.domain }})</small>
          </template>
          <template v-else>
            <router-link :to="`/item/${news.id}`">{{ news.title }}</router-link><small><a class="link-text" :href="news.domain" v-if="news.domain">({{ news.domain }})</a></small>
          </template>
        </p>
        <small v-if="news.user" class="link-text">
          by
          <router-link :to="`/user/${news.user}`" class="link-text">{{ news.user }}</router-link>
        </small>
        <small v-if="news.time_ago" class="link-text">
          {{ news.time_ago }}
        </small>
      </div>
    </li>
  </ul>
</template>

<script>
export default {
  // 이렇게하면 화면 실시간 갱신은 못함...
  // 어떻게 해야되지?
  data() {
    return {
      listItems: [],
    }
  },
  created() {
    this.listItems = this.$store.getters.fetchedList;
  }
  // computed: {
  //   listItems() {
  //     return this.$store.getters.fetchedList;
  //   }
  // }
}
</script>

<style scoped>
.news-list {
  padding: 0;
  margin: 0;
}
.post {
  list-style: none;
  display: flex;
  align-items: center;
  border-bottom: 1px solid #eee;
}
.points {
  width: 80px;
  height: 60px;
  color: #42b883;
  display: flex;
  align-items: center;
  justify-content: center;
}
.link-text {
  color: #828282;
}
.news-title {
  margin: 0;
}
</style>


8.2.1.2 해결책 2. computed가 계속 store의 list 값 바라보게.. 하지만 이것도 결국 안돼. created랑 내부 돌아가는 과정은 다르지만 같은 결과..



<template>
  <ul class="news-list">
    <li v-for="news in listItems" :key="news.id" class="post">
      <div class="points">
        {{ news.points || 0 }}
      </div>
      <div>
        <p class="news-title">
          <template v-if="news.domain">
            <a :href="news.url">{{ news.title }}</a><small class="link-text" v-if="news.domain">({{ news.domain }})</small>
          </template>
          <template v-else>
            <router-link :to="`/item/${news.id}`">{{ news.title }}</router-link><small><a class="link-text" :href="news.domain" v-if="news.domain">({{ news.domain }})</a></small>
          </template>
        </p>
        <small v-if="news.user" class="link-text">
          by
          <router-link :to="`/user/${news.user}`" class="link-text">{{ news.user }}</router-link>
        </small>
        <small v-if="news.time_ago" class="link-text">
          {{ news.time_ago }}
        </small>
      </div>
    </li>
  </ul>
</template>

<script>
export default {
  // 아래와 같이 바꿔봤자 화면엔 라우트 네임이 바뀌어야 갱신
  // 아까와 다르게 computed 에서 store 의 list 값을 바라보곤 있지만,
  // 그래서 list 값이 바뀌었을 경우 실행되긴 하지만,
  // 어차피 route name이 안달라지면 화면에 갱신 안함
  // 흠... 실시간 화면 갱신은 이러나 저러나 포기해야될듯?
  data() {
    return {
      routeName: '',
      fetchedListItems: [],
    }
  },
  created() {
    this.routeName = this.$route.name;
    this.fetchedListItems = this.$store.getters.fetchedList;
  },
  computed: {
    listItems() {
      if (this.routeName === this.$route.name) {
        return this.fetchedListItems;
      }
      this.fetchedListItems = this.$store.getters.fetchedList;
      return this.$store.getters.fetchedList;
    }
  }
}
</script>

<style scoped>
.news-list {
  padding: 0;
  margin: 0;
}
.post {
  list-style: none;
  display: flex;
  align-items: center;
  border-bottom: 1px solid #eee;
}
.points {
  width: 80px;
  height: 60px;
  color: #42b883;
  display: flex;
  align-items: center;
  justify-content: center;
}
.link-text {
  color: #828282;
}
.news-title {
  margin: 0;
}
</style>


8.2.1.3 결국 내가 원하는대로 하려면(실시간 갱신도 가능한데, 전환효과 까지 잘 하게하려면) listItem 컴포넌트로 공통화 말고 3개로 다 나눠야하나.. 그방법말곤 없나?

  • 일단 원본 형태로 가자
  • 이 문제를 해결하려면 컴포넌트를 통일화 못하고 3개로 나눠야하나.. 아니면 created를 사용해야하나..
  • 현재 뭐 실시간 기능이 적용된건 아니니까.. 실시간 적용하려면 API를 주기적으로 호출하거나 아니면 주기적으로 백단에서 data를 쏴주거나… 그래야되니깐
  • 그냥 created로 가면될거같긴 함
Note

일단 created로 수정해서 가자!!!!