본문 바로가기

Vue.js

[Udemy Vue 완벽가이드 Section16] 254. 로딩 아이콘 렌더링

Requests로 갔다가 다시 All Coaches화면으로 가면, 백그라운드에서 새로운 코치들을 로딩하고 있다는 아무런 표시가 없다.

→ 최적화된 앱이라고 할 수 없다.

 

UI를 업데이트할 수 있는 컴포넌트에서 하면 좋겠지만, Vuex 저장소(store)에서 HTTP요청을 보내고 있기 때문에 충돌이 발생할 수 있다.

 

코치 데이터를 가져오는 동안, 로딩 아이콘을 표시하여 페이지를 새로고침할 때 발생하는 깜박임을 없애보자.

먼저 로딩아이콘이 필요하다.

첨부한 BaseSpinner.vue를 사용해서 CoachesList.vue페이지에 로딩아이콘을 렌더링하자.

 

 

Vuex를 사용하면 요청을 보내는 중에도 로딩여부를 확인할 수 있다.

액션을 dispatch할 때 좋은 기능이 있는데 이 기능이 필요한 상황이 없었어서 사용해본 적은 없다.

 

 

dispatch에는 호출하는 컴포넌트에 promise를 반환하는 기능이 있다.

actions.js에서 loadCoaches액션을 dispatch하는 경우, async 키워드를 사용하므로 모든 단계가 완료되면 resolve할 promise를 자동으로 반환한다.

// actions.js
async loadCoaches(context) {
    const response = await fetch(
      `https://vue-main-prj-01-9bcae-default-rtdb.firebaseio.com/coaches.json`
    );
    const responseData = await response.json();
    const coaches = [];
    for (const key in responseData) {
      const coach = {
        id: key,
        firstName: responseData[key].firstName,
        lastName: responseData[key].lastName,
        areas: responseData[key].areas,
        description: responseData[key].description,
        hourlyRate: responseData[key].hourlyRate,
      };
      coaches.push(coach);
    }
    console.log('coaches', coaches);

    context.commit('setCoaches', coaches);
  },

좋은 기능이다.

promise가 반환되면 CoachesList.vue에서 promise완료 여부를 수신대기하고 있다가, promise가 완료되면 로딩을 멈출 수 있다.

 

CoachesList.vue 컴포넌트에 새로운 data 프로퍼티를 추가해보자.

isLoading: false

 

loadCoaches메서드가 실행될 때는 isLoading값이 true여야 한다.

그런 다음, 요청을 dispatch한 후, 액션이 완료되면, 즉 dispatch에 의해 반환된 promise가 resolve되면 더이상 loading하지 않는다.

dispatch가 promise를 반환하므로 async/await을 이용하여 프로미스의 완료를 대기할 수 있다.

promise가 완료돠면, isLoading을 false로 설정한다.

async loadCoaches() {
  this.isLoading = true;
  await this.$store.dispatch('coaches/loadCoaches');
  this.isLoading = false;
},

이제 로딩 아이콘을 표시할 수 있다.

 

main.js에 BaseSpinner.vue를 전역 컴포넌트로 등록해주자.

computed 프로퍼티인 hasCoachees도 수정해야한다.

 <div v-if="isLoading">
   <base-spinner></base-spinner>
 </div>
 <ul v-if="hasCoachees">

위 목록은 코치가 있으면서 로딩되지 않는 경우에만 렌더링되어야하기 때문. 로딩중이라면 사라져야한다.

 

따라서 hasCoaches 프로퍼티를 수정해보자.

this.isLoading을 추가해, 현재 로딩 중인지도 확인해보자.

computed: {
 hasCoaches() {
      return this.$store.getters['coaches/hasCoaches'] && !this.isLoading;
   },
}

 

이렇게 하니, 지금은 로딩아이콘과 함께 'No coaches found.' 문구도 같이 뜬다.

v-if, v-else-if, v-else를 이용하여 문제를 해결해보자.

 

"Register as Coache"버튼도 로딩 중에는 안보이도록 v-if="isLoading"을 이용해보자.

<base-button link to="/register" v-if="!isCoach && !isLoading">Register as Coach</base-button>

 

 

** 출처: 모든 내용은 Udemy Vue-완벽가이드 강의를 기반으로 작성하였습니다.