## 前言:
由于我們打開網(wǎng)頁時(shí),瀏覽器與服務(wù)器交互需要時(shí)間,受限于寬帶以及服務(wù)器性能,導(dǎo)致用戶在訪問一個網(wǎng)頁時(shí),往往需要一個等待期,才能在瀏覽器中真正完全展示出網(wǎng)頁內(nèi)容。在網(wǎng)頁加載過程中網(wǎng)頁就是一片空白,對于我們用戶而言,我們看到一片空白,還以為網(wǎng)站 "掛掉了",就很憂傷!!
當(dāng)然了,我們針對這個問題,各大網(wǎng)站都有自己的解決方案。
有的網(wǎng)站會用骨架屏。
比如掘金:利用骨架屏,給用戶提醒,網(wǎng)站內(nèi)容馬上呈現(xiàn)給您,不要著急!
有的網(wǎng)站會選擇在數(shù)據(jù)出來之前 定義一個全屏的loading,提供用于網(wǎng)站正在加載
比如:網(wǎng)站在加載時(shí)以及網(wǎng)站刷新時(shí),會彈出全屏loading。
## 文章目的:
今天我們就要帶大家實(shí)現(xiàn),在vue開發(fā)的前后端分離應(yīng)用中,實(shí)現(xiàn)在網(wǎng)頁加載以及刷新時(shí),實(shí)現(xiàn)如上圖全屏loading的效果!
### 功能分析
vue項(xiàng)目中所有的請求一般都是通過axios,所以我們需要給axios新增請求和響應(yīng)攔截,在請求攔截中顯示loading,和響應(yīng)攔截中關(guān)閉loading。
所以我們需要定義兩個全局方法,一個是顯示loading,叫$showLoading(),另一個叫$hideLoading()關(guān)閉全屏loading。
### 代碼實(shí)現(xiàn)
上面的梳理,我們明確了,需要定義兩個全局方法,一個顯示loading一個關(guān)閉loading,這里我們定義一個Vue的插件通過插件動態(tài)給實(shí)例安裝 顯示和關(guān)閉Loading方法。
- 定義$loading插件,在Vue構(gòu)造函數(shù)原型上添加兩個方法
以下loading.js代碼
```text
const $loading = {
install: (Vue) => {
// 添加 顯示loading方法
Vue.prototype.$showLoading = () => {
console.log('loading顯示')
}
// 添加關(guān)閉loading方法
Vue.prototype.$hideLoading = () => {
console.log('loading關(guān)閉')
}
}
}
export default $loading;
// 使用時(shí) 在main.js入口函數(shù)中引入 使用插件即可安裝
Vue.use($loading)
```
- 添加axios請求和響應(yīng)攔截,調(diào)用顯示和關(guān)閉loading方法
```text
import Vue from 'vue'
// 定義Vue實(shí)例 調(diào)用全局顯示和關(guān)閉loading方法
const vm = new Vue()
// 請求攔截
axios.interceptors.request.use(function (config) {
// 在這里調(diào)用 顯示loading方法
vm.$showLoading()
return config
}, function (error) {
vm.$hideLoading()
// 在請求出錯調(diào)用 關(guān)閉loading方法
return Promise.reject(error)
})
// 響應(yīng)攔截
axios.interceptors.response.use(function (response) {
// 在這里調(diào)用 關(guān)閉loading方法
vm.$hideLoading()
return response
}, function (error) {
// 在這里調(diào)用 關(guān)閉loading方法
vm.$hideLoading()
return Promise.reject(error)
}
```
此時(shí)首頁有三次請求,顯示了三次loading顯示和loading關(guān)閉!
當(dāng)然我們 在數(shù)據(jù)請求不是打印,而是 顯示loading,數(shù)據(jù)過來時(shí)應(yīng)該關(guān)閉loading,所以接下來我們實(shí)現(xiàn)這兩個效果
- 通過單文件組件 定義顯示loading結(jié)構(gòu)
我們目前的問題是,在顯示loading時(shí)不是打印而是要顯示全局loading的html結(jié)構(gòu),在關(guān)閉loading時(shí)要隱藏!
為了實(shí)現(xiàn)這個需求,我們通過vue的單文件組件來定義loading的html結(jié)構(gòu)和控制loading顯示隱藏
loading.vue
```text
<template>
<!--
mask是loading的背景 v-show控制loading顯示消失
-->
<div class="mask" v-show="isShow">
<div class="loading"></div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
// loading默認(rèn)不顯示
isShow: false
}
}
}
</script>
<style lang="scss">
// 定義動畫 控制 loading旋轉(zhuǎn)
@keyframes rotate {
0%{
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.mask{
position: fixed;
left:0;
right:0;
top:0;
bottom:0;
background-color: rgba(0,0,0,.7);
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
.loading{
width: 30px;
height: 30px;
border: 6px solid rgb(219, 140, 13);
border-radius: 21px;
border-left-color:transparent;
animation: rotate 500ms infinite;
}
}
</style>
```
- loading.js中獲取單文件組件 html結(jié)構(gòu) 并在 $showLoading方法調(diào)用時(shí)顯示,在$hideLoading時(shí)隱藏
loading.js中
```js
import LoadingVue from './loading.vue'
const $loading = {
install: (Vue) => {
// 通過 Vue.extend方法 獲取LoadingComponent 組件 類
const LoadingComponent = Vue.extend(LoadingVue);
// new LoadingComponent得到組件的實(shí)例
const vm = new LoadingComponent();
// 獲取組件實(shí)例的html 并插入到body中
const tpl = vm.$mount().$el;
// 插入到body中
document.body.appendChild(tpl);
// 添加 顯示loading方法
Vue.prototype.$showLoading = () => {
// 通過改變實(shí)例 .mask v-show綁定變量控制顯示
vm.isShow = true
}
// 添加關(guān)閉loading方法
Vue.prototype.$hideLoading = () => {
// 通過改變實(shí)例 .mask v-show綁定變量控制隱藏
vm.isShow = false
}
}
}
```
最后在main.js中使用插件 在axios攔截器中控制顯示隱藏就ok啦!!
main.js
```js
import Vue from 'vue'
import loading from './plugins/loading'
Vue.use(loading)// 構(gòu)造函數(shù)原型上就添加了$showLoading和$hideLoading方法
```
axios攔截器中使用
```js
import Vue from 'vue'
// 定義Vue實(shí)例 調(diào)用全局顯示和關(guān)閉loading方法
const vm = new Vue()
// 請求攔截
axios.interceptors.request.use(function (config) {
// 在這里調(diào)用 顯示loading方法
vm.$showLoading()
return config
}, function (error) {
vm.$hideLoading()
// 在請求出錯調(diào)用 關(guān)閉loading方法
return Promise.reject(error)
})
// 響應(yīng)攔截
axios.interceptors.response.use(function (response) {
// 在這里調(diào)用 關(guān)閉loading方法
vm.$hideLoading()
return response
}, function (error) {
// 在這里調(diào)用 關(guān)閉loading方法
vm.$hideLoading()
return Promise.reject(error)
}
```
是不是很棒,好啦我們的vue全屏loading插件到這里就完成了,小伙伴們回去試一試吧。
更多關(guān)于web培訓(xùn)的問題,歡迎咨詢千鋒教育在線名師。千鋒教育擁有多年IT培訓(xùn)服務(wù)經(jīng)驗(yàn),采用全程面授高品質(zhì)、高體驗(yàn)培養(yǎng)模式,擁有國內(nèi)一體化教學(xué)管理及學(xué)員服務(wù),助力更多學(xué)員實(shí)現(xiàn)高薪夢想。