阅读next.js路由文档
This commit is contained in:
126
react/next.js.md
126
react/next.js.md
@@ -68,3 +68,129 @@ root layout使用需要满足如下条件
|
|||||||
- root layout必须要定义`<html>`标签和`<body>`标签,next.js并不会自动创建它们
|
- root layout必须要定义`<html>`标签和`<body>`标签,next.js并不会自动创建它们
|
||||||
- 如果layout.js存在多层嵌套,例如`/layout.js`和`/about/layout.js`,`/about/asahi/layout.js`都存在,那么嵌套结构将是layout.js->about/layout.js->about/asahi/layout.js->about/asahi/page.js,其中about/asahi/page.js渲染的效果将会包含上层所有的layout
|
- 如果layout.js存在多层嵌套,例如`/layout.js`和`/about/layout.js`,`/about/asahi/layout.js`都存在,那么嵌套结构将是layout.js->about/layout.js->about/asahi/layout.js->about/asahi/page.js,其中about/asahi/page.js渲染的效果将会包含上层所有的layout
|
||||||
|
|
||||||
|
#### template
|
||||||
|
template和layout相似,在template中也可以包含子page和子layout。
|
||||||
|
|
||||||
|
|
||||||
|
layout和template区别如下:
|
||||||
|
- layout在route跳转时,layout本身维护的state会保持不变
|
||||||
|
- 而template在route跳转时,**对于其每一个children,都会含有一个独立的template实例**,template在多个route进行跳转时,state不会持久化
|
||||||
|
|
||||||
|
> 故而,只有在layout中维护的state才会保持不变,而template中维护的state,在route之间进行跳转时,会清空
|
||||||
|
|
||||||
|
可以通过创建一个template.js文件并且在文件中export default一个组件来定义template
|
||||||
|
```js
|
||||||
|
export default function Template({ children }) {
|
||||||
|
return <div>{children}</div>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
如果一个route segment同时具有template和layout,那么渲染输出如下所示:
|
||||||
|
```js
|
||||||
|
<Layout>
|
||||||
|
{/* Note that the template is given a unique key. */}
|
||||||
|
<Template key={routeParam}>{children}</Template>
|
||||||
|
</Layout>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 修改head
|
||||||
|
在app目录中,可以自定义html文件的head标签的属性,例如`title`和`meta`。
|
||||||
|
需要在page.js或layout.js中导出一个metadata的对象:
|
||||||
|
```js
|
||||||
|
export const metadata = {
|
||||||
|
title: 'Next.js',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return '...';
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### linking and navigating
|
||||||
|
#### Link组件
|
||||||
|
`<Link>`是一个html组件,该组件继承了html`<a>`元素,用于提供routes之间的预取和导航。该组件是react组件之间进行跳转的主要方法。
|
||||||
|
如果要使用Link组件,需要从`next/link`中导入该组件,并且在组件的href属性中写入目标路径:
|
||||||
|
```js
|
||||||
|
import Link from 'next/link';
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return <Link href="/dashboard">Dashboard</Link>;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
#### 路由到动态的路径
|
||||||
|
如果想要路由到动态的路径,可以按照如下方式:
|
||||||
|
```js
|
||||||
|
// 在路径字符串中,可以通过${}来动态获取值
|
||||||
|
import Link from 'next/link';
|
||||||
|
|
||||||
|
export default function PostList({ posts }) {
|
||||||
|
return (
|
||||||
|
<ul>
|
||||||
|
{posts.map((post) => (
|
||||||
|
<li key={post.id}>
|
||||||
|
<Link href={`/blog/${post.slug}`}>{post.title}</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
#### 跳转到目标的element
|
||||||
|
默认情况下,Link会跳转到目标route页面的顶部,如果想要跳转到目标route的指定位置,可以在href中加入`#${id}`。
|
||||||
|
```js
|
||||||
|
<Link href="/#hashid" scroll={false}>
|
||||||
|
Scroll to specific id.
|
||||||
|
</Link>
|
||||||
|
```
|
||||||
|
#### useRouter
|
||||||
|
useRouter允许client component在代码中触发路由的跳转,如果要使用useRouter,需要导入`next/navigation`中的`useRouter`:
|
||||||
|
```js
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button type="button" onClick={() => router.push('/dashboard')}>
|
||||||
|
Dashboard
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### route group
|
||||||
|
在app文件夹中,通过通过文件路径结构来表示url path,如果想要一个文件夹不影响url path,可以将其标识为route group。
|
||||||
|
|
||||||
|
如果要创建route group,可以用小括号将目录名包起来,形式如下`
|
||||||
|
(foldername)`。
|
||||||
|
|
||||||
|
#### 在不影响url path的情况下组织目录结构
|
||||||
|
为了在不影响url path的情况下组织目录结构,可以通过如下方式来使用route group,其中route group文件夹将会在url path中被忽略:
|
||||||
|
```bash
|
||||||
|
app/(market)/about # 该url对应为/about
|
||||||
|
app/(shop)/account # 该url对应为/account
|
||||||
|
```
|
||||||
|
> 即使在使用route group时,(market)和(shop)文件夹下共享同一路径'/',但是可以在(market)目录和(shop)目录下创建不同的layout.js文件
|
||||||
|
|
||||||
|
可以通过在(market)和(shop)下创建不同的layout.js,位于(market)下的组件共享makretLayout,位于(shop)下的组件共享shopLayout。
|
||||||
|
|
||||||
|
同理,可以通过route group创建多个root layout。
|
||||||
|
|
||||||
|
### 动态路由
|
||||||
|
当不知道确切的segment name,并且想要根据动态数据来创建route segment,可以使用动态路由。
|
||||||
|
|
||||||
|
可以通过将文件夹名称通过`[]`包围起来来创建动态路由,例如`app/blog/[slug]/page.js`。
|
||||||
|
动态数据将会被作为params参数传入,动态路由使用如下所示:
|
||||||
|
```js
|
||||||
|
// app/blog/[slug]/page.js
|
||||||
|
// params:{ slug: 'a' } url:/blog/a
|
||||||
|
// params:{ slug: 'b' } url:/blog/b
|
||||||
|
export default function Page({ params }) {
|
||||||
|
return <div>My Post</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user