You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13 App目录下页面导航进度条实现求助

Next.js 13 App目录实现页面切换进度条

方法一:自定义进度条组件

App目录下的路由事件API与旧Pages目录不同,需使用next/navigation导出的useRouter监听路由变化:

  1. 创建客户端组件components/ProgressBar.tsx:
'use client';

import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';

export default function ProgressBar() {
  const [progress, setProgress] = useState(0);
  const router = useRouter();

  useEffect(() => {
    const startProgress = () => setProgress(30);
    const finishProgress = () => {
      setProgress(100);
      setTimeout(() => setProgress(0), 300);
    };

    // 绑定路由切换事件
    router.events.on('routeChangeStart', startProgress);
    router.events.on('routeChangeComplete', finishProgress);
    router.events.on('routeChangeError', finishProgress);

    // 组件卸载时移除监听
    return () => {
      router.events.off('routeChangeStart', startProgress);
      router.events.off('routeChangeComplete', finishProgress);
      router.events.off('routeChangeError', finishProgress);
    };
  }, [router]);

  return (
    <div 
      className="fixed top-0 left-0 right-0 h-1 bg-blue-500 z-50 transition-all duration-500 ease-out"
      style={{ width: `${progress}%` }} 
    />
  );
}
  1. 在根布局app/layout.tsx中引入组件:
import ProgressBar from '@/components/ProgressBar';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="zh-CN">
      <body>
        <ProgressBar />
        {children}
      </body>
    </html>
  );
}

可通过修改className和内联样式,自定义进度条的颜色、高度、动画速度等。

方法二:使用第三方库NProgress

NProgress是成熟的进度条工具,适配App目录路由事件即可使用:

  1. 安装依赖:
npm install nprogress
# 或
yarn add nprogress
  1. 创建客户端组件components/NProgressBar.tsx:
'use client';

import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import { useEffect } from 'react';
import { useRouter } from 'next/navigation';

export default function NProgressBar() {
  const router = useRouter();

  useEffect(() => {
    const start = () => NProgress.start();
    const finish = () => NProgress.done();

    router.events.on('routeChangeStart', start);
    router.events.on('routeChangeComplete', finish);
    router.events.on('routeChangeError', finish);

    return () => {
      router.events.off('routeChangeStart', start);
      router.events.off('routeChangeComplete', finish);
      router.events.off('routeChangeError', finish);
    };
  }, [router]);

  return null;
}
  1. 在根布局中引入组件,同时可在app/globals.css中自定义NProgress样式:
/* 自定义进度条样式 */
#nprogress .bar {
  background: #2563eb;
  height: 3px;
}

#nprogress .peg {
  box-shadow: 0 0 12px #2563eb, 0 0 6px #2563eb;
}

关键注意事项

  • 所有依赖useRouter的组件必须添加'use client'指令,App目录默认是服务器组件,无法访问客户端路由API。
  • 根布局作为服务器组件,可直接导入客户端组件,Next.js会自动处理客户端边界。
  • 需给routeChangeError绑定结束逻辑,避免页面切换出错时进度条卡住。

内容的提问来源于stack exchange,提问作者RORN DEV

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 23:50:06