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