본문 바로가기
개발/게시판 만들기

[Vue] Vue.js 게시판 만들기 15 - 데이터 로딩 나타내기

by onethejay 2022. 7. 4.
728x90

지난 포스팅까지 진행하여 로그인 처리를 구현해봤습니다.
이번에는 로딩바를 통해 현재 서버와 통신중임을 사용자에게 안내하여 기다릴 수 있도록 해보고자합니다.

화면에서 서버로 어떤 작업을 요청했을 때, 서버의 처리가 오래 걸리게 되면 화면은 응답을 계속 기다리게 됩니다.
사용자는 현재 작업중인지 완료되었는지 알 수 없으므로 화면에서 벗어나지 않고 대기할 수 있도록 표시해주어야 합니다.

Vuex에 로딩 상태 추가

전역으로 로딩 상태를 관리하기 위해 아래 작업을 진행합니다.

먼저 mutation_types.js에 LOADING_STATUS를 추가합니다.

/* src/vuex/mutation_types.js */
export const USER_ID = 'USER_ID'
export const ERROR_STATE = 'ERROR_STATE'
export const IS_AUTH = 'IS_AUTH'
export const LOADING_STATUS = 'LOADING_STATUS'

이어서 mutations.js에 LOADING_STATUS 타입을 추가합니다.

/* src/vuex/mutation.js */
import * as types from './mutation_types'

export default {
    [types.USER_ID] (state, userId) {
        state.userId = userId
    },
    [types.ERROR_STATE] (state, errorState) {
        state.errorState = errorState
    },
    [types.IS_AUTH] (state, isAuth) {
        state.isAuth = isAuth
    },
    [types.LOADING_STATUS] (state, loadingStatus) {
        state.loadingStatus = loadingStatus
    }
}

다음으로 store.js에 state에 loadingStatus를 추가합니다.

/* src/vuex/store.js */

import {createStore} from "vuex";
import getters from "./getters";
import mutations from "./mutations";
import actions from "./actions";

export const store = createStore({
  state: {
    user: null,
    isLogin: false,
    loadingStatus: false,
  },
  mutations,
  getters,
  actions
});

LoadingBar 컴포넌트 생성

화면에 로딩중임을 나타낼 로딩바 컴포넌트를 생성합니다.

common/LoadingBar.vue 파일을 생성하고 아래 내용을 추가합니다.

<template>

  <div class="lds-facebook" v-if="loading">
    <div>
    </div>
    <div>
    </div>
    <div>
    </div>
  </div>

</template>

<script>
  export default {
    props: {
      loading: {
        type: Boolean,
        required: true,
      },
    },
  }
</script>

<style>
  .lds-facebook {
    display: inline-block;
    position: fixed;
    width: 64px;
    height: 64px;
    top: 50%;
    left: 50%;
  }

  .lds-facebook div {
    display: inline-block;
    position: absolute;
    left: 6px;
    width: 13px;
    background: #42b883;
    animation: lds-facebook 1.2s cubic-bezier(0, 0.5, 0.5, 1) infinite;
  }

  .lds-facebook div:nth-child(1) {
    left: 6px;
    animation-delay: -0.24s;
  }

  .lds-facebook div:nth-child(2) {
    left: 26px;
    animation-delay: -0.12s;
  }

  .lds-facebook div:nth-child(3) {
    left: 45px;
    animation-delay: 0;
  }

  @keyframes lds-facebook {
    0% {
      top: 6px;
      height: 51px;
    }

    50%,
    100% {
      top: 19px;
      height: 26px;
    }
  }
</style>

LoadingBar 컴포넌트 추가

프로젝트의 메인 App.vue에 LoadingBar 컴포넌트를 추가합니다

<template>
  <Header/> <!-- 헤더 컴포넌트 -->
  <router-view/>  <!-- 페이지 이동이 표시될 곳 -->
  <Footer/> <!-- 푸터 컴포넌트 -->
  <LoadingBar :loading="this.$store.state.loadingStatus"></LoadingBar>
</template>

<script>
import Header from '@/components/Header'
import Footer from '@/components/Footer'
import LoadingBar from '@/views/common/LoadingBar'

export default {
  name: 'App',
  components: {
    Footer,
    Header,
    LoadingBar
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}
</style>

axios에 상태 제어 추가

axios의 전역 설정에 vuex store의 LOADING_STATUS 상태를 제어하는 함수를 추가합니다.

import axios from 'axios';
import {store} from '@/vuex/store'

axios.interceptors.request.use(function (config) {
  store.commit('LOADING_STATUS', true)

  const token = localStorage.getItem('user_token');
  config.headers.Authorization = "Bearer " + token;
  return config;
});

axios.interceptors.response.use(function (config) {
  store.commit('LOADING_STATUS', false)

  return config
});

export default axios;

로딩바 확인하기

서버와 통신하고 있을 경우 로딩바가 표시되며 통신이 완료되면 로딩바가 사라집니다.

728x90

댓글