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钩子里。函数

相关文章
相关标签/搜索