vue多頁面項目使用全局Loading組件

多頁面vue應用中,在請求接口以前統一加上Loading做爲未請求到數據以前的過渡展現。
因爲多頁面未使用vuex作狀態管理,只在入口統一註冊了bus,因此此例子使用eventbus作事件通訊。vue

在Loading.vue中,一個簡單的公共loading組件

這個loading組件用showLoading控制展現與否。ajax

<template>
  <div class="loading" v-show="showLoading">
    <img/>
    <p>加載中...</p>
  </div>
</template>

Loading.vue中,用bus接收全局事件,控制組件的顯示隱藏

用SHOW_LOADING和HIDE_LOADING事件控制組件的顯示隱藏vuex

<script>
import { Bus, SHOW_LOADING, HIDE_LOADING } from 'utils/bus'
export default {
  name: 'loading',
  data () {
    return {
      showLoading: false
    }
  },
  created () {
    this.loadingFn()
  },
  methods: {
    loadingFn () {
      Bus.$on(SHOW_LOADING, () => {
        this.showLoading = true
      })

      Bus.$on(HIDE_LOADING, () => {
        this.showLoading = false
    }
  },
}
</script>

ajax請求中統一作處理

以ajax請求爲例,能夠在beforeSend和complete鉤子函數中emit對應的隱藏和顯示事件。json

new Promise((resolve, reject) => {
    let defaultOpt = {
      url,
      type: config.method || 'POST',
      data: params || {},
      timeout: 50000,
      contentType: 'application/x-www-form-urlencoded',
      dataType: json
    }

    defaultOpt.beforeSend = (xhr, settings) => {
      if(config.setLoad){
        Bus.$emit(SHOW_LOADING)
      } else {
        Bus.$emit(HIDE_LOADING)
      }
    }

    defaultOpt.complete = () => {
      Bus.$emit(HIDE_LOADING)
    }

    $.ajax(defaultOpt)
  })

將bus註冊在多頁面的應用的main.js中

因爲每一個頁面都有可能用到這個效果,這時候會在全局註冊一些公共的組件,這樣哪一個頁面須要用到,不須要從新引入,直接調用組件便可。app

import Vue from 'vue'
import App from './App.vue'
import bus from 'utils/bus'
import components from 'utils/components.js'

// 註冊統一的bus應用
Vue.prototype.$bus = bus
// 全局註冊組件
Vue.use(components)

new Vue({
  render: h => h(App)
}).$mount('#app')

components.js裏放置須要全局註冊的組件

import Loading from 'components/Loading.vue'
export default (Vue) => {
  Vue.component('Loading', Loading),
  // 其餘組件
}

額外須要注意的

用的時候直接引入到須要的頁面便可。
可是會有一個小小的問題,假設某個頁面在created裏就要請求接口,這時候Bus.$emit(SHOW_LOADING) 會沒法被接收到。由於這時候Loading組件還未能加載完成,Bus.$on(SHOW_LOADING)還未能註冊上。因此,臨時的解決方案是將請求先放在mounted鉤子裏。函數

相關文章
相關標籤/搜索