后台管理系統loading的局部刷新
在一次vue+element-ui后台管理系統的項目中,遇到這樣一個問題,引入element-ui加載框后,loading會占滿整個屏幕,雖然通過改變路由實現了局部刷新,但是loading的全屏刷新,讓人看上去很是不爽,以為是全局刷新。再一個問題就是,一個頁面中可能含有的多個請求,在攔截器匯總設置關閉loading后,會出現的問題就是,有些數據還是空的,但是loading框就已經關閉了我們需要實現的是所有請求完成后關閉loading。所以這是另一個問題。
所以為了解決這兩個問題做此總結,幫助更多的小伙伴脫坑。
如果要實現全局的刷新則可以查看博主的另一片總結:
傳送門
沒有思路就沒有出路,先說思路:
局部的loading框的出現,element-ui在vue中引入后,就會默認在vue原型鏈上掛在一個loaiding方法,可以通過vue.prototype.$loading看到,解決問題的關鍵就在這個方法中,該方法中可以設置這么幾個屬性lock,text,target,background,我們搞清楚這些,問個問題也就迎刃而解。lock可以看作是loading的開關,text則是loading的文本的提示信息。target則是根據類型顯示需要出現loading的區域。background則是loading的bgcolor
所有請求完成后再關閉loading,默認大家都知道vue攔截器。解決思路比較簡單,創建一個定時器,在request時,num++,在response時num--當num<=0時,則所有請求都有了結果,這個時候我們就可以關閉loading了。
情景及Demo
后台管理系統,header,aside,main,除了loading,404外,實現main的局部刷新,且所有請求完成后再關閉loading框。 先看我們的網絡請求層,封裝的fetch.js文件.
import axios from 'axios' import { Message} from 'element-ui' import router from '../router/permission' import Vue from 'vue' // loading框設置局部刷新,且所有請求完成后關閉loading框 let loading; function startLoading() { loading = Vue.prototype.$loading({ lock: true, text: "Loading...", target: document.querySelector('.loading-area')//設置加載動畫區域 }); } function endLoading() { loading.close(); } //聲明一個對象用於存儲請求個數 let needLoadingRequestCount = 0; function showFullScreenLoading() { if (needLoadingRequestCount === 0) { startLoading(); } needLoadingRequestCount++; }; function tryHideFullScreenLoading() { if (needLoadingRequestCount <= 0) return; needLoadingRequestCount--; if (needLoadingRequestCount === 0) { endLoading(); } }; // 請求攔截 axios.interceptors.request.use(config => { showFullScreenLoading(); return config; }, err => { tryHideFullScreenLoading(); Message.error({ message: '請求超時!' }); return Promise.resolve(err); }) // 響應攔截 axios.interceptors.response.use(res => { tryHideFullScreenLoading(); if (res.data.code == 200) { return res.data.result; } else if (res.data.code == 401) { router.push('/login'); return Promise.reject(res); } else if (res.data.code == 201) { Message.error({ message: res.data.msg }); return Promise.reject(res); } return Promise.reject(res); }, err => { tryHideFullScreenLoading(); if (err.response.status == 504 || err.response.status == 404) { Message.error({ message: '服務器被吃了⊙﹏⊙∥' }); } else if (err.response.status == 403) { Message.error({ message: '權限不足,請聯系管理員!' }); } else { Message.error({ message: '未知錯誤' }); } return Promise.reject(err); }) let base = ''; export const postRequest = (url, params) => { return axios({ method: 'post', url: `${base}${url}`, data: params, transformRequest: [function (data) { let ret = '' for (let it in data) { ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&' } return ret }], headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); } export const getRequest = (url, data = '') => { return axios({ method: 'get', params: data, url: `${base}${url}` }); }
下來我們就需要查看我們的主入口文件Home.vue.
<template> <!-- 布局 --> <el-container> <el-header class="header-wraper" > <admin-header></admin-header> </el-header> <el-container class="container"> <el-aside > <admin-aside></admin-aside> </el-aside> <el-main class="loading-area"> <keep-alive> <router-view v-if="this.$route.meta.keepAlive"></router-view> </keep-alive> <router-view v-if="!this.$route.meta.keepAlive"></router-view> </el-main> </el-container> </el-container> </template> <script> import AdminAside from '@/components/Commons/Aside/index'; import AdminHeader from '@/components/Commons/Header/index' export default { components: { AdminAside, AdminHeader }, data () { return {} }, } </script> <style lang="less" scoped> .header-wraper { width: 100%; height: 70px; border-bottom: 1px solid #ccc; overflow: hidden; } .container { width: 100%; height: 100%; } </style>
關鍵實現以上兩部就可實現頭部預覽效果局部刷新。