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

Next.js 13/14 App目录下如何在路由切换时显示顶部加载条?

在Next.js 13/14中实现页面切换顶部加载条(兼容Link与router.push)

方案一:App Router内置加载状态(基础页面骨架屏)

如果只需要页面级的加载占位提示,Next.js App Router自带loading.tsx功能:在对应路由目录下创建loading.tsx文件,就能在页面加载时显示骨架屏或自定义加载动画。但这种方式不是顶部进度条,适合需要页面级占位的场景。

方案二:自定义顶部加载条(推荐,适配所有跳转方式)

要实现顶部进度条且兼容Link组件和router.push(),可以通过监听路由全局事件实现,步骤如下:

1. 创建全局LoadingBar组件

在app/components目录下新建LoadingBar.tsx:

'use client';

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

export default function LoadingBar() {
  const [isLoading, setIsLoading] = useState(false);
  const router = useRouter();
  const pathname = usePathname();

  useEffect(() => {
    // 定义加载状态切换函数
    const startLoading = () => setIsLoading(true);
    const stopLoading = () => setIsLoading(false);

    // 监听路由核心事件
    router.events.on('routeChangeStart', startLoading);
    router.events.on('routeChangeComplete', stopLoading);
    router.events.on('routeChangeError', stopLoading);

    // 组件卸载时清理监听事件
    return () => {
      router.events.off('routeChangeStart', startLoading);
      router.events.off('routeChangeComplete', stopLoading);
      router.events.off('routeChangeError', stopLoading);
    };
  }, [router]);

  // 监听路径变化,覆盖边缘场景
  useEffect(() => {
    setIsLoading(true);
    // 防止瞬间跳转时加载条无显示
    const timer = setTimeout(() => setIsLoading(false), 300);
    return () => clearTimeout(timer);
  }, [pathname]);

  return (
    <div
      className={`fixed top-0 left-0 right-0 h-1 bg-blue-500 z-50 transition-all duration-300 ease-in-out ${
        isLoading ? 'w-full' : 'w-0'
      }`}
    />
  );
}

2. 在根布局中全局引入

打开app/layout.tsx,将LoadingBar放在<body>最顶部,确保它能覆盖所有页面:

import LoadingBar from './components/LoadingBar';

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

3. 解决router.push()无效的核心逻辑

之前使用工具包仅Link组件生效,是因为工具包可能只监听了Link的点击事件,未覆盖路由系统的全局事件。这里通过router.events监听Next.js路由的三个核心事件:

  • routeChangeStart:无论点击Link还是调用router.push(),路由跳转开始时都会触发
  • routeChangeComplete:路由跳转成功完成时触发
  • routeChangeError:路由跳转失败(如404、网络错误)时触发
    这三个事件能覆盖所有路由跳转场景,确保加载条同步响应。

额外优化建议

  • 可修改加载条样式:比如换成渐变背景、调整动画时长,或添加进度模拟(如从0%到80%,完成时直接跳到100%)
  • Next.js 13.4+支持useRouter的isPending状态,可结合该状态实现更精细的进度控制
  • 可根据不同路由路径动态调整加载条颜色,适配页面风格

内容的提问来源于stack exchange,提问作者Nested Gateway

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 01:11:29