多页面vue应用中,在请求接口之前统一加上Loading作为未请求到数据之前的过渡展示。
由于多页面未使用vuex做状态管理,只在入口统一注册了bus,所以此例子使用eventbus做事件通信。

在Loading.vue中,一个简单的公共loading组件

这个loading组件用showLoading控制展示与否。

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

Loading.vue中,用bus接收全局事件,控制组件的显示隐藏

用SHOW_LOADING和HIDE_LOADING事件控制组件的显示隐藏

<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对应的隐藏和显示事件。

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中

由于每个页面都有可能用到这个效果,这时候会在全局注册一些公共的组件,这样哪个页面需要用到,不需要重新引入,直接调用组件即可。

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