進度指示器

由於 Inertia 請求是透過 XHR 發出的,因此在從一個頁面導航到另一個頁面時,通常不會有瀏覽器載入指示器。為了解決這個問題,Inertia 會在您進行 Inertia 訪問時,在頁面頂部顯示進度指示器。

當然,如果您願意,您可以停用 Inertia 的預設載入指示器,並提供您自己的自訂實作。我們將在下面討論這兩種方法。

預設

Inertia 的預設進度指示器是圍繞 NProgress 函式庫的輕量級包裝。您可以使用 createInertiaApp() 函式的 progress 屬性來自訂它。 NProgress 函式庫。您可以使用 progress createInertiaApp() 函數的屬性來自訂它。

createInertiaApp({
  progress: {
    // The delay after which the progress bar will appear, in milliseconds...
    delay: 250,

    // The color of the progress bar...
    color: '#29d',

    // Whether to include the default NProgress styles...
    includeCSS: true,

    // Whether the NProgress spinner will be shown...
    showSpinner: false,
  },
  // ...
})

您可以將 progress 屬性設定為 false.

createInertiaApp({
  progress: false,
  // ...
})

自訂

也可以使用 Inertia 事件 設定您自己的自訂頁面載入指示器。讓我們以 NProgress 函式庫為例,探討如何執行此操作。

首先,停用 Inertia 的預設載入指示器。

createInertiaApp({
  progress: false,
  // ...
})

接下來,安裝 NProgress 函式庫。

npm install nprogress

安裝後,您需要將 NProgress 樣式新增至您的專案。您可以使用樣式的 CDN 主機副本執行此操作。 樣式新增至您的專案。您可以使用樣式的 CDN 主機副本執行此操作。

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.css" />

接下來,將 NProgress 和 Inertia router 匯入您的應用程式。

import NProgress from 'nprogress'
import { router } from '@inertiajs/vue3'

接下來,讓我們新增一個 start 事件監聽器。我們將使用此監聽器在新 Inertia 訪問開始時顯示進度列。

router.on('start', () => NProgress.start())

然後,讓我們新增一個 finish 事件監聽器,以便在頁面訪問完成時隱藏進度列。

router.on('finish', () => NProgress.done())

就這樣!現在,當您從一個頁面導航到另一個頁面時,進度列將會被新增和移除。

處理已取消的訪問

雖然此自訂進度實作對於正常完成的頁面訪問運作良好,但最好也處理已取消的訪問。首先,對於中斷的訪問(因新的訪問而取消的那些訪問),進度列應簡單地重置回起始位置。其次,對於手動取消的訪問,進度列應立即從頁面移除。

我們可以透過檢查提供給 finish 事件的 event.detail.visit 物件來完成此操作。

router.on('finish', (event) => {
  if (event.detail.visit.completed) {
    NProgress.done()
  } else if (event.detail.visit.interrupted) {
    NProgress.set(0)
  } else if (event.detail.visit.cancelled) {
    NProgress.done()
    NProgress.remove()
  }
})

檔案上傳進度

讓我們更進一步。當檔案正在上傳時,最好更新載入指示器以反映上傳進度。可以使用 progress 事件來完成此操作。

router.on('progress', (event) => {
  if (event.detail.progress.percentage) {
    NProgress.set((event.detail.progress.percentage / 100) * 0.9)
  }
})

現在,當檔案正在上傳時,進度列不會「涓滴」,而是會根據請求的進度實際更新其位置。我們在這裡將進度限制為 90%,因為我們仍然需要等待伺服器的回應。

載入指示器延遲

我們將要實作的最後一件事是載入指示器延遲。通常較佳的做法是延遲顯示載入指示器,直到請求超過 250-500 毫秒。這可以防止載入指示器在快速頁面訪問時不斷出現,這可能會在視覺上分散注意力。

為了實作延遲行為,我們將使用 setTimeoutclearTimeout 函數。讓我們首先定義一個變數來追蹤逾時。

let timeout = null

接下來,讓我們更新 start 事件監聽器,以啟動一個新的逾時,該逾時會在 250 毫秒後顯示進度列。

router.on('start', () => {
  timeout = setTimeout(() => NProgress.start(), 250)
})

接下來,我們將更新 finish 事件監聽器,以清除在頁面訪問在逾時之前完成時的任何現有逾時。

router.on('finish', (event) => {
  clearTimeout(timeout)
  // ...
})

finish 事件監聽器中,我們需要確定進度列是否已實際開始顯示進度,否則我們將會在逾時完成之前無意中導致其顯示。

router.on('finish', (event) => {
  clearTimeout(timeout)
  if (!NProgress.isStarted()) {
    return
  }
  // ...
})

而且,最後,我們需要在 progress 事件監聽器中執行相同的檢查。

router.on('progress', event => {
  if (!NProgress.isStarted()) {
    return
  }
  // ...
}

就這樣,您現在就有一個美觀的自訂頁面載入指示器了!

完整範例

為了方便起見,以下是我們自訂載入指示器最終版本的完整原始碼。

import NProgress from 'nprogress'
import { router } from '@inertiajs/vue3'

let timeout = null

router.on('start', () => {
  timeout = setTimeout(() => NProgress.start(), 250)
})

router.on('progress', (event) => {
  if (NProgress.isStarted() && event.detail.progress.percentage) {
    NProgress.set((event.detail.progress.percentage / 100) * 0.9)
  }
})

router.on('finish', (event) => {
  clearTimeout(timeout)
  if (!NProgress.isStarted()) {
    return
  } else if (event.detail.visit.completed) {
    NProgress.done()
  } else if (event.detail.visit.interrupted) {
    NProgress.set(0)
  } else if (event.detail.visit.cancelled) {
    NProgress.done()
    NProgress.remove()
  }
})