From a85ca5838204f36f42f7861971acb439165c1bc0 Mon Sep 17 00:00:00 2001
From: xjccc <546534045@qq.com>
Date: Sat, 15 Feb 2025 03:01:26 +0800
Subject: [PATCH] feat(nuxt): allow forcing `start`/`set` in loading indicator
(#30989)
---
.../2.composables/use-loading-indicator.md | 15 ++++++++++++++-
.../src/app/composables/loading-indicator.ts | 17 +++++++++--------
test/nuxt/composables.test.ts | 17 +++++++++++++++++
3 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/docs/3.api/2.composables/use-loading-indicator.md b/docs/3.api/2.composables/use-loading-indicator.md
index 357c260bbd..9d112ed764 100644
--- a/docs/3.api/2.composables/use-loading-indicator.md
+++ b/docs/3.api/2.composables/use-loading-indicator.md
@@ -40,7 +40,11 @@ It hooks into [`page:loading:start`](/docs/api/advanced/hooks#app-hooks-runtime)
### `start()`
-Set `isLoading` to true and start to increase the `progress` value.
+Set `isLoading` to true and start to increase the `progress` value. `start` accepts a `{ force: true }` option to skip the interval and show the loading state immediately.
+
+### `set()`
+
+Set the `progress` value to a specific value. `set` accepts a `{ force: true }` option to skip the interval and show the loading state immediately.
### `finish()`
@@ -62,3 +66,12 @@ Used by `finish()`. Clear all timers and intervals used by the composable.
})
```
+
+```vue
+
+```
diff --git a/packages/nuxt/src/app/composables/loading-indicator.ts b/packages/nuxt/src/app/composables/loading-indicator.ts
index b3c0a86455..e3d1031d79 100644
--- a/packages/nuxt/src/app/composables/loading-indicator.ts
+++ b/packages/nuxt/src/app/composables/loading-indicator.ts
@@ -24,8 +24,8 @@ export type LoadingIndicator = {
progress: Ref
isLoading: Ref
error: Ref
- start: () => void
- set: (value: number) => void
+ start: (opts?: { force?: boolean }) => void
+ set: (value: number, opts?: { force?: boolean }) => void
finish: (opts?: { force?: boolean, error?: boolean }) => void
clear: () => void
}
@@ -49,23 +49,24 @@ function createLoadingIndicator (opts: Partial = {}) {
let hideTimeout: number | NodeJS.Timeout
let resetTimeout: number | NodeJS.Timeout
- const start = () => {
+ const start = (opts: { force?: boolean } = {}) => {
error.value = false
- set(0)
+ set(0, opts)
}
- function set (at = 0) {
+ function set (at = 0, opts: { force?: boolean } = {}) {
if (nuxtApp.isHydrating) {
return
}
- if (at >= 100) { return finish() }
+ if (at >= 100) { return finish({ force: opts.force }) }
clear()
progress.value = at < 0 ? 0 : at
- if (throttle && import.meta.client) {
+ const throttleTime = opts.force ? 0 : throttle
+ if (throttleTime && import.meta.client) {
throttleTimeout = setTimeout(() => {
isLoading.value = true
_startProgress()
- }, throttle)
+ }, throttleTime)
} else {
isLoading.value = true
_startProgress()
diff --git a/test/nuxt/composables.test.ts b/test/nuxt/composables.test.ts
index 425660839d..97a600b762 100644
--- a/test/nuxt/composables.test.ts
+++ b/test/nuxt/composables.test.ts
@@ -530,6 +530,23 @@ describe('loading state', () => {
})
})
+describe('loading state', () => {
+ it('expect state from set opts: { force: true }', async () => {
+ vi.stubGlobal('setTimeout', vi.fn((cb: () => void) => cb()))
+ const nuxtApp = useNuxtApp()
+ const { isLoading, start, finish, set } = useLoadingIndicator()
+ await nuxtApp.callHook('page:loading:start')
+ start({ force: true })
+ expect(isLoading.value).toBeTruthy()
+ finish()
+ expect(isLoading.value).toBeFalsy()
+ set(0, { force: true })
+ expect(isLoading.value).toBeTruthy()
+ set(100, { force: true })
+ expect(isLoading.value).toBeFalsy()
+ })
+})
+
describe.skipIf(process.env.TEST_MANIFEST === 'manifest-off')('app manifests', () => {
it('getAppManifest', async () => {
const manifest = await getAppManifest()