Progress Bar(進度條)---NProgress
當你打開一個頁面,頁面顯示空白或者部分空白,那么用戶就會懷疑你的網頁是不是有問題。我們需要讓我們的用戶知道數據在路上,當他們點擊一個需要請求數據鏈接時,就會給出反饋,讓用戶知道頁面的加載情況
1.NProgress相關的三種方案
- 借用Axios攔截器組合實現
- 通過組件內的路由守衛實現
- 通過路由的全局前置守衛實現
2.解決方案1:NProgress與axios interceptors
首先我們來安裝(NProgress)
1$ npm 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秒。
總結:這是一個有效的解決方案,可能對你很有用,但有兩個注意事項你應該知道。
- 不適合同時進行多個API調用
在我們使用兩個或更多的API調用來加載頁面之前,這種方法需要一些改進。在這個場景中,我們希望持續顯示進度條,直到所有API調用返回為止。此問題的常見解決方案是創建一個保存加載狀態的加載Vuex模塊。
- 在返回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,有兩種方法:
- 在頁面中使用beforeRouteEnter生命周期函數,但是這里推薦使用下一種方案
- 在路由列表中使用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從組件中移除,優化了組件,使其更加具有維護性
長按二維碼關注公眾號
