前言

先附上源码地址:next-ts-seed

上一篇文章介绍了Next.js14的App Router的根本运用:一文整理Next.js 14的App Router,本篇继续解说App Router的一些高档用法

对Next.js14项目建立还不熟悉的,可参考我的另一篇文章:给上市公司从0到1建立Next.js14项目

1. 动态路由的静态参数

例如博客页面,博客1的路由为/blogs/1,博客2的路由为/blogs/2,博客的id都是固定的,不会随着用户的每次恳求而变化。

对于这些动态路由,可运用 generateStaticParams 界说路由中的静态参数,这些参数在构建时会被预先核算并用于生成静态页面。然后进步页面的功能和效率。

generateStaticParams回来一个数组,数组中的每一项为页面的静态参数,页面经过params去接纳。

例如回来[{ id: ‘1’ }, { id: ‘2’ }]。{ id: ‘1’ }为一个页面的静态参数,在props中经过params获取到 {id: ‘1’ }

新建src/app/blog/[id]/page.tsx

export async function generateStaticParams() {
  //const products = await fetch('https://.../products').then((res) => res.json())
  //模拟经过接口回来一切id信息
  return [{ id: '1' }, { id: '2' }];
}
export default async function Blog({ params }: { params: { id: string } }) {
  //可经过id去恳求接口,获取博客详情页
  return <div>{params.id}博客页面</div>;
}

运行npm run builld进行打包,在.next/server/app/blog文件夹下,能够看到生成了2个html文件,分别为1.html,2.html。都各自预烘托了相应内容

【Next.js 进阶】App Router的高档用法(上)

相比于用户恳求时再创建相应页面,在构建时预烘托页面,显然能显著的进步页面的打开速度

2. 路由加载

当进行路由跳转,进入一个新页面时,假如需要发送恳求以获取页面数据。因为接口呼应存在推迟,页面在这段时间内可能会呈现无法交互的状况。咱们能够运用加载UI与流式传输技术,进步用户体验。

  1. 新建app/home/page.tsx

页面嵌套Suspense组件

import { Suspense } from 'react';
import { Spin } from 'antd';
import List from './components/list';
export default function Home() {
  return (
    <article>
      我是首页
      <Suspense fallback={<Spin />}>
        <List />
      </Suspense>
    </article>
  );
}
  1. 新建app/home/components/list.tsx

getProjects方法模拟了一个接口,2s后回来成果

async function getProjects(): Promise<{ name: string; id: number }[]> {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve([
        {
          name: 'zhang',
          id: 1,
        },
        {
          name: 'li',
          id: 2,
        },
      ]);
    }, 2000);
  });
}
export default async function List() {
  const projects = await getProjects();
  return (
    <div className="App">
      {projects.map((o: any) => (
        <div key={o.id}>{o.name}</div>
      ))}
    </div>
  );
}

改写页面,浏览器将先显现loading加载状况,之后再显现页面内容

留意点:不要在最外层去恳求接口,因为await等待接口时,异步组件不会去烘托,其他不依赖接口的页面也会显现不出来。正确做法应如示例中,在List子组件中恳求数据,在页面组件Home中运用Suspense包裹子组件。假如页面组件中想恳求接口,可在layout文件顶用Suspense包裹页面组件。

提示:在Suspense中显现的服务端组件,不会影响SEO,依旧能够被获取到。可将自己的网站部署后,拜访:search.google.com/test/rich-r…,进行SEO测验

我这里将getProjects里边的内容替换成接口数据,并进行SEO测验。接口中的内容能够被正常抓取:

【Next.js 进阶】App Router的高档用法(上)

【Next.js 进阶】App Router的高档用法(上)

3. 并行路由

1. 根本运用

平行路由能够使你在同一个布局中一起或许有条件的烘托一个或许多个页面。文件夹以@作为最初进行命名,这个文件夹下面的 page.js 将会主动注入文件夹同级 layout 的 props 中

  1. 新建平行路由analytics

新建app/home/@analytics/page.tsx

export default function Page() {
  return <h1>剖析页</h1>;
}
  1. 新建平行路由team

新建app/home/@team/page.tsx

export default function Page() {
  return <h1>团队页</h1>;
}
  1. 新建/home的布局文件

新建app/home/layout.tsx

export default function Layout({
  children,
  team,
  analytics,
}: {
  children: React.ReactNode;
  analytics: React.ReactNode;
  team: React.ReactNode;
}) {
  return (
    <section>
      {children}
      {team}
      {analytics}
    </section>
  );
}

重启项目,拜访路由/home,页面内容如下所示

【Next.js 进阶】App Router的高档用法(上)

2. 约定文件 default

default.tsx是并行路由的回退页面,也就是说当匹配不到并行路由时,会显现并行路由下default.tsx的内容

  1. 新建app/home/user/page.tsx
export default function Page() {
  return <h1>用户页</h1>;
}

此刻拜访路由“/home/user”,页面会显现404,分明创立了该文件,为什么拜访不到?

因为app/home/layout.tsx文件中界说了三个插槽,分别为children,team,analytics。user下的page.tsx默许匹配了children,但team和analytics两个插槽没匹配上,因而会报404页面,可在并行路由下界说default.tsx

  1. 新建app/home/@analytics/default.tsx
export default function Page() {
  return <h1>剖析页的默许页</h1>;
}
  1. 新建app/home/@team/default.tsx
export default function Page() {
  return <h1>team的默许页</h1>;
}

此刻再拜访路由“/home/user”,页面将显现

用户页
team的默许页
剖析页的默许页

假如不想拜访home的子路由被并行路由插槽影响时,default.tsx可回来一个null,将@analytics/default.tsx,@team/default.tsx分别改为

export default function Page() {
  return null;
}

再拜访路由“/home/user”,页面将显现

用户页

3. 并行路由的子路由

在并行路由的根本运用中,完成了将analytics和team插入到home的layout中。当然运用组件也能完成同样的作用,接下来看并行路由与组件的不同点:并行路由能够创建自己的子路由

  1. 新建app/home/@analytics/behavior/page.tsx
export default function Page() {
  return <h1>行为剖析</h1>;
}
  1. 新建app/home/@analytics/performance/page.tsx
export default function Page() {
  return <h1>功能剖析</h1>;
}
  1. 新建app/home/@analytics/layout.tsx,进行布局
import Link from 'next/link';
export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <>
      <nav>
        <Link href="/home/behavior">behavior Views</Link>
        ----------
        <Link href="/home/performance">performance Views</Link>
      </nav>
      <div>{children}</div>
    </>
  );
}

在拜访路由时,并行路由@最初的文件名可省掉,例如这里app/home/@analytics/behavior/page.tsx对应着路由“/home/behavior”,拜访/home/behavior页面显现404,这是为什么?

因而在app/home/layout.tsx中,咱们界说了三个插槽children,team,analytics,此刻拜访并行路由“/home/behavior”,意味着只匹配上了插槽analytics,而children,team没有匹配上,在之前咱们界说了@team/default.tsx,但没有界说默许插槽children的回退内容

  1. 新建app/home/default.tsx
export default function Page() {
  return <div>home的默许页</div>;
}

再次拜访路由“/home/behavior”,页面将会正常显现:

【Next.js 进阶】App Router的高档用法(上)

并行路由仍是有上手难度的,主张了解后再运用

结尾

因为约定式文件路由真正上手起来仍是有难度的,最起码比react-router-dom 和vue-router难,因而这里将Next.js14的App Router分隔来解说,假如对App Router感兴趣的,可先关注我,后续将继续更新相关内容

参考资料:

nextjs.org/docs/app/bu…