news 2026/10/6 2:30:51

VueUse useNProgress 实战:为 Vue 3 应用接入响应式顶部进度条

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
VueUse useNProgress 实战:为 Vue 3 应用接入响应式顶部进度条
  • 前端

【免费下载链接】vueuse

Collection of essential Vue Composition Utilities for Vue 3

项目地址:https://gitcode.com/gh_mirrors/vu/vueuse
点击查看免费下载

useNProgress是 VueUse Integrations 系列中对nprogress的响应式封装,让你以 Vue 原生的 Ref 语法驱动经典的顶部细进度条。本文基于 VueUse 仓库中 useNProgress 的参考文档 与 源码实现,完整讲解安装、基础用法、进度百分比控制与样式定制,并结合源码剖析其响应式联动原理。读完本文,你将掌握如何用寥寥几行代码为路由切换、异步请求等场景接入一个可声明式控制的进度条。

背景:为什么需要响应式封装

nprogress是一个轻量、无依赖的顶部进度条库,其核心 API 是命令式的start()、done()、set(n)与configure(options)。在 Vue 3 的组合式 API 语境下,命令式调用难以与模板、watch等响应式机制直接联动。useNProgress的做法是把命令式 API 包装成Ref与WritableComputedRef,让进度状态成为组件数据流的一部分。在 VueUse 仓库中它位于 Integrations 包内,并由 packages/integrations/index.ts 统一导出。

安装与依赖说明

useNProgress是一个集成封装,本身不打包nprogress,因此需要单独安装:

npm i nprogress@^0

如果使用 pnpm,还可一并安装类型声明:

pnpm add nprogress@^0 pnpm add -D @types/nprogress

在 packages/integrations/package.json 中,nprogress被声明为可选 peer 依赖("nprogress": "^0.2",并在peerDependenciesMeta中标记optional: true),意味着你只在使用该函数时才需要安装它,不会强制拖入无关依赖。

基础用法:声明式开关 isLoading

使用方式非常直接——从@vueuse/integrations/useNProgress子路径导入:

import { useNProgress } from '@vueuse/integrations/useNProgress' const { isLoading } = useNProgress() function toggle() { isLoading.value = !isLoading.value }

isLoading是一个WritableComputedRef<boolean, boolean>:把isLoading.value置为true会调用nprogress.start()让进度条开始流动,置为false则调用nprogress.done()让进度条收尾并淡出。因此在模板中可以直接绑定:

<button @click="isLoading = !isLoading"> {{ isLoading ? 'Stop' : 'Start' }} </button>

这段写法的演示可参见仓库中的 useNProgress/demo.vue,它还展示了配合progress实时显示百分比:

<b v-if="isLoading" class="ml-2">{{ ((progress || 0) * 100).toFixed(0) }}%</b>

底层联动原理

从源码 packages/integrations/useNProgress/index.ts 可以看到isLoading的完整定义:

const isLoading = computed({ set: load => load ? nprogress.start() : nprogress.done(), get: () => typeof progress.value === 'number' && progress.value < 1, })

get的判定逻辑是:只有当progress是数字且小于1时才算"加载中"。这与nprogress的语义一致——进度到达1即表示完成。由此isLoading既能手动写入(驱动进度条),也能从当前进度反推出加载状态(供模板展示),实现双向联动。

控制进度百分比:progress Ref

useNProgress的第一个参数用于传入初始进度,支持数字、Ref或 getter 函数(MaybeRefOrGetter<number | null | undefined>):

const { progress } = useNProgress(0.5) function done() { progress.value = 1.0 }

要改变进度百分比,只需设置progress.value = n,其中n是0..1之间的数字。默认参数为null,表示进度条处于"未知进度"的流动状态。

源码中的同步机制

源码对进度的同步做了两层处理(packages/integrations/useNProgress/index.ts):

const setProgress = nprogress.set nprogress.set = (n: number) => { progress.value = n return setProgress.call(nprogress, n) } watchEffect(() => { if (typeof progress.value === 'number' && isClient) setProgress.call(nprogress, progress.value) })
  • 第一处:拦截并重写nprogress.set。当nprogress内部因自动递增而更新进度时,同步写回progress.value,保证 Ref 始终反映真实进度;
  • 第二处:watchEffect反向驱动。当外部修改progress.value为数字时,调用底层的set把进度推给nprogress,且通过isClient(来自@vueuse/shared)在服务端渲染时跳过 DOM 操作,保证 SSR 安全。

这种双向同步正是"响应式封装"的核心价值:无论进度来自手动赋值、路由守卫还是nprogress内部逻辑,progressRef 都能保持一致。

配置项:第二个参数 options

可以通过第二个参数传入配置对象来定制行为,例如设置进度条的最小初始值:

import { useNProgress } from '@vueuse/integrations/useNProgress' useNProgress(null, { minimum: 0.1, // 其他 nprogress 配置项 })

options的类型是UseNProgressOptions = Partial<NProgressOptions>(packages/integrations/useNProgress/index.ts),即nprogress全部配置项的浅层可选子集,常见可用项包括:

配置项作用典型值
minimum起始最小进度,避免刚启动就跳到过高的百分比0.08起,示例中使用0.1
easing进度条运动的缓动函数名'ease'、'linear'
speed进度条动画速度(毫秒)200
trickle是否启用自动递增的小步前进true
trickleSpeed自动递增的时间间隔(毫秒)200
showSpinner是否显示右上角旋转加载圈true/false
parent进度条挂载的父容器元素'body'或某个 DOM 元素

这些配置会通过nprogress.configure(options)一次性应用到全局(packages/integrations/useNProgress/index.ts),因此适合在应用初始化时统一配置。

样式定制

进度条的外观由nprogress自带的 CSS 控制。最直接的做法是修改nprogress.css中你喜欢的部分——通常只需查找并替换主题色#29d(nprogress 的默认蓝色)即可。

仓库中的示例 useNProgress/style.css 提供了一套可参考的自定义样式:它把主色替换为绿色#67d391,保留#nprogress上pointer-events: none(让点击事件穿透进度条),并为进度条.bar设置了position: fixed、z-index: 1031、top: 0、height: 2px的顶部细条布局,同时用.peg的box-shadow实现右侧发光拖尾效果。在自己的项目中,引入自定义样式的方式与 demo 一致:

import { useNProgress } from '@vueuse/integrations/useNProgress' import './style.css'

如果需要把进度条限制在某个局部容器内(而不是全屏顶部),可以配合parent配置项指定容器,并给容器添加nprogress-custom-parent类(样式文件中有对应的绝对/相对定位规则)。

返回的完整 API

useNProgress返回一个包含五个成员的对象(packages/integrations/useNProgress/index.ts):

export interface UseNProgressReturn { isLoading: WritableComputedRef<boolean, boolean> progress: Ref<number | null | undefined> start: () => NProgress done: (force?: boolean) => NProgress remove: () => void }
成员类型说明
isLoadingWritableComputedRef<boolean>读写双向:置true调用start(),置false调用done();读取时按progress < 1判断
progressRef<number \| null \| undefined>当前进度百分比(0..1),可读可写
start() => NProgress启动进度条(透传自nprogress.start)
done(force?: boolean) => NProgress结束进度条,force为true时强制立即完成
remove() => void移除进度条 DOM,同时将progress重置为null

注意done(force)支持一个可选的force参数:传true时跳过淡出动画,立即移除进度条。而remove的语义更彻底——源码中它同时把progress.value重置为null并调用nprogress.remove()(packages/integrations/useNProgress/index.ts),适合在组件卸载或需要彻底清除进度条时使用。

生命周期自动清理

一个值得关注的细节:源码在函数末尾调用了tryOnScopeDispose(nprogress.remove)(packages/integrations/useNProgress/index.ts)。

tryOnScopeDispose来自@vueuse/shared(导出见 packages/shared/index.ts),它的语义是:如果当前存在活跃的 effect scope(如组件实例或手动effectScope),就在作用域销毁时自动执行清理回调;否则直接忽略。这意味着当使用useNProgress的组件被卸载,或包裹它的effectScope被释放时,进度条会自动移除,无需手动清理,避免进度条残留在页面上或产生内存泄漏。

典型应用场景

把以上能力组合起来,最常见的落地场景是路由级加载指示。以 Vue Router 为例,在全局前置守卫中结合isLoading即可实现"跳转期间显示进度条":

import { useNProgress } from '@vueuse/integrations/useNProgress' const { isLoading, done } = useNProgress(null, { showSpinner: false }) router.beforeEach(() => { isLoading.value = true }) router.afterEach(() => { done() })

异步请求场景中,也可以用progress精确反映上传/下载进度,或对多个并行请求统一以start/done收口。由于isLoading、progress都是标准的响应式引用,它们天然可以放进watch、计算属性或组件模板中,与 Vue 3 的组合式 API 生态无缝衔接。

小结

  • useNProgress是nprogress的响应式薄封装,核心价值在于把命令式 API 转换为isLoading/progress两个响应式引用,并保持双向同步;
  • 安装时需单独引入nprogress(可选 peer 依赖),样式可参考 style.css 自定义,配置通过第二个参数传入;
  • 通过重写nprogress.set与watchEffect实现进度双向同步,借助tryOnScopeDispose实现组件卸载自动清理;
  • 官方参考文档 useNProgress.md 与源码 index.ts、demo.vue 可直接对照阅读,是理解该函数最权威的第一手资料。
  • 前端

【免费下载链接】vueuse

Collection of essential Vue Composition Utilities for Vue 3

项目地址:https://gitcode.com/gh_mirrors/vu/vueuse
点击查看免费下载

相关推荐

上一篇:Claude Code 代码现代化插件(code-modernization)实战指南:从 COBOL 遗留系统到可验证的新架构
下一篇:魔兽争霸3终极重生指南:5分钟让经典游戏在Windows 11上流畅运行

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/6 2:26:03

【SI_IOP 01】深入掌握以太网100BASE-T1/1000BASE-T1 IOP测试

1. IOP概述 以太网 IOP(Interoperability Test,互操作性测试),特指车载以太网物理层 IOP,核心是验证不同厂商 PHY(收发器)与 ECU 间能否稳定建链、协同工作,遵循OPEN Alliance TC8规范(100/1000BASE-T1)。 目的:确保多供应商车载以太网设备(PHY/ECU)在真实工况下…

作者头像 李华
网站建设 2026/10/6 2:24:58

基于Spring Boot的玉林地区农产品销售平台的设计与开发

一、选题的目的和意义本选题的核心目的&#xff0c;是解决百色市非遗文化宣传与管理中的现存痛点&#xff0c;搭建一个集宣传、展示、管理、互动于一体的数字化平台[1]。当前百色市拥有丰富的非遗资源&#xff0c;但存在传播渠道单一、信息分散、管理模式传统等问题&#xff0c…

作者头像 李华