tohokuaikiのチラシの裏

技術的ネタとか。

VueのAjax通信の前後で共通のLoaderを入れる

ajaxの前後でLoading画面を出すやつです。

なんか、スゲー探してようやく見つけた…。
最初、Vuexを使わないようにしてたら全然できなくて、Vuexを使ったら30分でできて時間返してって感じだった。Vuexは恐れずに使え。

main.js

import Vue from 'vue';
import VueRouter from 'vue-router';
import Vuex from 'vuex'
import router from 'router';

window.Vue = require('vue');
Vue.use(VueRouter);
Vue.use(Vuex)

// loading状態を管理するためのVuex
const store = new Vuex.Store({
    state: {
        loadingCount: 0
    },
    mutations: {
        startLoader: (state) => {
            state.loadingCount++;
        },
        endLoader: (state) => {
            if (state.loadingCount > 0) {
                state.loadingCount--;
            }
        }
    }
});

// メインVue
const app = new Vue({
    el: '#app',
    router,
    store,
    components: {
        'my-vue-loading': MyVueLoading
    },
    computed: {
        loading() {
            return store.state.loadingCount > 0;
        }
    },
    created: function () {
        axios.interceptors.request.use(async config => {
            store.commit('startLoader');
            return config;
        });
        axios.interceptors.response.use(response => {
            store.commit('endLoader');
            return response;
        }, error => {
            store.commit('endLoader');
            throw error;
      });
    }
});

このcreatedに挟むのが分からんかった…

Loaderを使いたい時

router-viewを含むHTMLで

<div v-show="loading">Loading...</div>
<div v-show="!loading"><router-view></router-view></div>

な感じで。