為頁面/接口添加加載進度條


Progress Bar(進度條)---NProgress

當你打開一個頁面,頁面顯示空白或者部分空白,那么用戶就會懷疑你的網頁是不是有問題。我們需要讓我們的用戶知道數據在路上,當他們點擊一個需要請求數據鏈接時,就會給出反饋,讓用戶知道頁面的加載情況

1.NProgress相關的三種方案

  1. 借用Axios攔截器組合實現
  2. 通過組件內的路由守衛實現
  3. 通過路由的全局前置守衛實現

2.解決方案1:NProgress與axios interceptors

首先我們來安裝(NProgress)

1npm install nprogress

安裝好了NProgress,我們需要在main.js中引入它的CSS

1import 'nprogress/nprogress.css'

最后在axios插件中引入NProgress

1import NProgress from 'nprogress'

NProgress提供四個基本API

 1NProgress.start()// 開始展示進度條
2NProgress.set(0.4)// 設置進度百分比
3NProgress.inc()// 以隨機量遞增進度
4NProgress.done()// 完成進度條
5// 配置進度條
6NProgress.configure({
7    minimum: 0.08// 配置開始初始值,默認0.08
8    template: `
9        <div class="bar" role="bar">
10            <div class="peg"></div>
11        </div>
12        <div class="spinner" role="spinner">
13            <div class="spinner-icon"></div>
14        </div>
15    `, // 配置模板
16    easing: 'linear'// 配置動畫
17    speed: 200//配置速度
18    trickle: true// 是否讓進度條自動增加
19    trickleSpeed: 200// 配置自動前進的頻率ms
20    showSpinner: true//是否顯示加載動畫,如下圖
21    parent: 'body' //配置掛載元素,即相對定位的元素
22})

在AXIOS攔截器中使用NProgress

AXIOS攔截器允許我們攔截我們的請求和響應,添加額外的功能,我們可以在其中啟動和停止進度條,一個簡單的功能如下所示:

1axios.interceptors.request.use(config => {
2    NProgress.start()
3    return config
4})
5axios.interceptors.response.use(response => {
6    NProgress.done()
7    return response
8})

正如您所看到的,AXIOS攔截器充當中間件,允許您在發出請求時或在接收到響應時運行某些代碼。

為了清楚的查看效果,我們需要模擬一個緩慢的API服務器。我們使用json-server插件(mock工具)作為開發API,我們編寫一個帶有假數據的data.json文件。

我們將使用以下命令運行我們的API服務器:

1$json-server -d 1500 data.json

使用-d 1500,API服務器將在返回數據之前添加1.5秒(1500毫秒)的延遲。現在在我們的瀏覽器中,我們看到進度條在完成請求和填充數據之前會持續1.5秒。

總結:這是一個有效的解決方案,可能對你很有用,但有兩個注意事項你應該知道。

  1. 不適合同時進行多個API調用

在我們使用兩個或更多的API調用來加載頁面之前,這種方法需要一些改進。在這個場景中,我們希望持續顯示進度條,直到所有API調用返回為止。此問題的常見解決方案是創建一個保存加載狀態的加載Vuex模塊。

  1. 在返回API調用之前首屏呈現一定的空白

在某些網頁上,在數據完全之前看到該頁的部分元素並不是很好的用戶體驗,最好是拿到數據后在進行渲染。我們來看看其他的方案

3.解決方案2:組件內的路由守衛beforeRouteEnter

同樣的我們按照nprogress,並在main.js中引入css

不同的是我們這次在對應的頁面組件中引入NProgress,而不是在請求中

實例如下:

 1//page.vue
2import store from './store'
3import NProgress from 'nprogress'
4
5//組件渲染之前的生命周期函數
6beforeRouteEnter(routeTo、routeFrom、next){
7    NProgress.start()// 啟動進度條
8    由於組件尚未創建,因此不能在此處使用this關鍵字。
9    store.dispatch('event/fetchEvent,routeTo.params.id).(data => {
10        console.log(data)// 獲取數據
11        NProgress.done()// 當操作完成時,完成進度條
12        next()// 只有調用此命令,導航才會繼續
13    })
14},
15

這樣我們就能確保獲取到組件渲染所需的數據后才渲染組件

3.解決方案3:路由全局守衛與單路由守衛Global and Per-Route Guards

同樣的先按照引入NProgress

在route.js中引入NProgress

 1// route.js
2// 在每個路由行為之前
3router.beforeach((routeTo, routeFrom, next) => {
4    //啟動路由進度條
5    NProgress.start()
6    next()
7})
8
9// 在每個路由行為之后
10router.afterEach(() => {
11    // 完成路由進度條
12    NProgress.done()
13})

這樣我們已經初步完成NProgress的布置,但是我們還是需要在確保頁面數據都請求到之后才執行router.afterEach,有兩種方法:

  1. 在頁面中使用beforeRouteEnter生命周期函數,但是這里推薦使用下一種方案
  2. 在路由列表中使用beforeEnter守衛,配合使用props,我們可以將vuex從頁面組件中移除,這樣我們的組件會變得更加的簡潔,也更容易維護
 1Vue.use(Router)
2
3const router = new Router({
4    mode: 'history',
5    routes: [
6        {
7            path: '/event/:id',
8            name: 'event-show',
9            component: EventShow,
10            props: true,
11            beforeEnter(routeTo, routeFrom, next) {
12                store.dispatch('event/fetchEvent', routeTo.params.id).then(event => {
13                    routeTo.params.event = event
14                    next()
15                })
16            }
17        }
18    ]
19}
20

單獨的配置路由列表,無數據請求的路由頁,進度條可以瞬間完成,配置beforeEnter的將等待數據請求成功后才渲染組件。

另外,這樣通過組件傳參的方式將數據傳遞到組件中,可以將vuex從組件中移除,優化了組件,使其更加具有維護性


長按二維碼關注公眾號


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM