next.js_路由
路由构建
- 以
acme.com/dashedboard/settings
路由为例- 第一个
/
代表app
目录 /dashboard
代表app/dashboard
目录/dashboard/settings
代表app/dashboard/settings
目录
- 第一个
- 访问
acme.com/
会自动访问app/page.js
文件 - 访问
acme.com/dashedboard
会自动访问到app/dashboard/page.js
文件 - 如果存在
app/test
空目录, 那么acme.com/test
路径不可访问
layout.js
-
如果一个目录中有
layout.js
目录, 那么对应的目录只会走layout.js文件, 而不会走page.js文件; 布局会包裹页面 -
layout.js中的基本设定
-
export default function RootLayout ({ children }) { return ( <html lang="en"> <body> {children} <div id="main"></div> </body> </html> ) }
-
有且只有layout.js文件中可以写入html与body标签, app目录下的layout.js中应该包含有html与body标签.
-
layout.js中的children, 在访问当前目录时引入的是page.js的结构; 在访问下级目录时引入的是下级目录的layout.js(下级目录的children引入的是同目录的page.js文件)
-
定义根布局
-
export default function RootLayout ({ children }) { return ( <html lang="en"> <body> <div id="mainLayout"> {children} </div> </body> </html> ) }
-
-
定义根页面
-
export default function RootPage () { return ( <div id="rootPage"> <h1>这是根页面的结构</h1> </div> ) }
-
-
访问
/
目录-
<div id="mainLayout"> <div id="rootPage"> <h1>这是根页面的结构</h1> </div> </div>
-
-
定义test1目录的layout.js与page.js
-
// /test1/page.js export default function Test1Page () { return ( <div id="testPage"> <h1>这是test1页面结构</h1> </div> ) }
-
// /test1/layout.js export default function Test1Layout ({ children }) { return ( <div> {children} <div id="test1Layout"></div> </div>) }
-
访问
/test1
-
<div id="mainLayout"> <div> <div id="testPage"> <h1>这是test1页面结构</h1> </div> <div id="test1Layout"></div> </div> </div>
-
-
-
-
template.js
-
template.js写在与layout.js同级目录下, 如下所示: 在根目录下创建
page.js
,layout.js
,template.js
-
// /app/page.js export default function RootPage () { return ( <div id="rootPage"> <h1>这是根页面的结构</h1> </div> ) }
-
// /app/layout.js export default function RootLayout ({ children }) { return ( <html lang="en"> <body> <div id="rootLayout"> {children} </div> </body> </html> ) }
-
// /app/template.js export default function RootTemplate ({ children }) { return ( <div id="rootTem1"> {children} </div> ) }
-
访问
/
路径, 得到以下的html结构-
<div id="rootLayout"> <div id="rootTem1"> <div id="rootPage"> <h1>这是根页面的结构</h1> </div> </div> </div>
-
-
在
/app/test1
目录下编写以下几个文件-
// /app/test1/page.js export default function Test1Page () { return ( <div id="testPage"> <h1>这是test1页面结构</h1> </div> ) }
-
// /app/test1/layout.js export default function Test1Layout ({ children }) { return ( <div id="test1Layout"> {children} </div>) }
-
// /app/test1/template.js export default function Test1Template ({ children }) { return ( <div id="test1Tem1"> {children} </div> ) }
-
-
访问
/test1
路径, 得到以下结构-
<div id="rootLayout"> <div id="rootTem1"> <div id="test1Layout"> <div id="test1Tem1"> <div id="testPage"> <h1>这是test1页面结构</h1> </div> </div> </div> </div> </div>
-
自定义head
-
使用
metadata
定义页面的head内容, metadata只能在page.js
与layout.js
中使用-
// /app/layout.js export const metadata = { title: 'root', description: 'root....' }
-
// /app/test1/layout.js export const metadata = { title: 'Test', description: 'Test....' }
-
如此便实现了访问不同的目录有不同的标题
-
link组件
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>
)
}
usePathname
-
您可以使用usePathname()来确定链接是否处于活动状态。例如,要将类添加到活动链接,可以检查当前路径名是否与链接的href匹配:
-
'use client' import { usePathname } from 'next/navigation' import Link from 'next/link' export function Links() { const pathname = usePathname() return ( <nav> <ul> <li> <Link className={`link ${pathname === '/' ? 'active' : ''}`} href="/"> Home </Link> </li> <li> <Link className={`link ${pathname === '/about' ? 'active' : ''}`} href="/about" > About </Link> </li> </ul> </nav> ) }
滚动到指定锚点
<Link href="/dashboard#settings">Settings</Link>
// Output
<a href="/dashboard#settings">Settings</a>
useRouter
'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/dashboard')}>
Dashboard
</button>
)
}
- 有
router.push
与router.replace
路由预取
<Link>
组件:当路线在用户的视口中可见时,会自动预取这些路线。预取发生在页面首次加载时或通过滚动进入视图时。- router.prefetch():useRouter钩子可用于以编程方式预取路由。
路由组
/app/(student)/list
/app/(teacher)/list
- 可以在
(student)
这些目录中添加layout.js等文件, 带括号的目录不会影响路由
创建多个根路由
- 要创建多个根布局,请删除顶级layout.js文件,并在每个路由组中添加一个layout.js文件。这对于将应用程序划分为具有完全不同的UI或体验的部分非常有用。
<html>
和<body>
标记需要添加到每个根布局中。
动态路由
-
例如,博客可以包括以下路径,其中是博客文章的动态分段。app/blog/[slug]/page.js[slug]
-
export default function Page({ params }) { return <div>My Post: {params.slug}</div> }
-
创建
/app/template/[id]/page.js
文件-
export default function templatePage({params}){ return ( <div id="tem">{params.id}</div> ) }
-
访问
/template/25
, 页面成功打印25
-