多页面vue应用中,在请求接口以前统一加上Loading做为未请求到数据以前的过渡展现。
因为多页面未使用vuex作状态管理,只在入口统一注册了bus,因此此例子使用eventbus作事件通讯。vue
这个loading组件用showLoading控制展现与否。ajax
<template> <div class="loading" v-show="showLoading"> <img/> <p>加载中...</p> </div> </template>
用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请求为例,能够在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) })
因为每一个页面都有可能用到这个效果,这时候会在全局注册一些公共的组件,这样哪一个页面须要用到,不须要从新引入,直接调用组件便可。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')
import Loading from 'components/Loading.vue' export default (Vue) => { Vue.component('Loading', Loading), // 其余组件 }
用的时候直接引入到须要的页面便可。
可是会有一个小小的问题,假设某个页面在created里就要请求接口,这时候Bus.$emit(SHOW_LOADING) 会没法被接收到。由于这时候Loading组件还未能加载完成,Bus.$on(SHOW_LOADING)还未能注册上。因此,临时的解决方案是将请求先放在mounted钩子里。函数