Next.js 提供了两种路由支持,静态路由与动态路由
静态路由
静态路由通过文件规范来约定,pages
目录下的js
文件都认为是路由(每个静态路由对应一个页面文件),例如:
pages/index.js → /
pages/blog/index.js → /blog
pages/blog/first-post.js → /blog/first-post
pages/dashboard/settings/username.js → /dashboard/settings/username
动态路由
类似的,动态路由也要在pages
目录下创建文件,只是文件名有些不同寻常:
// 类似于springmvc的的路由参数,获取路由变量
pages/blog/[slug].js → /blog/:slug (/blog/hello-world)
// 动态参数可以是任意位置
pages/[username]/settings.js → /:username/settings (/foo/settings)
// 不定量的动态参数
pages/post/[...all].js → /post/* (/post/2020/id/title)
路径中变化的参数通过getStaticPaths
来填充
注意下面是的形式是next.js约定好的
// pages/posts/[id].js
export async function getStaticPaths() {
return {
// 必须叫paths,值必须是数组
paths: [{
// 每一项必须是这个形式
params: {
// 必须含有id
id: 'ssg-ssr'
}
},{
params: {
id: 'pre-rendering'
}
}],
fallback: false
}
}
进一步传递给getStaticProps
按参数获取数据,并渲染页面:
// pages/posts/[id].js
export async function getStaticProps({ params }) {
// 根据路由参数获取相应数据
const postData = await getPostData(params.id)
return {
props: {
postData
}
}
}
// 渲染页面
export default function Post({ postData }) {
return (
<Layout>
<Head>
<title>{postData.title}</title>
</Head>
<article>
<h1 className={utilStyles.headingXl}>{postData.title}</h1>
<div className={utilStyles.lightText}>
<Date dateString={postData.date} />
</div>
<div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />
</article>
</Layout>
)
}
可以理解为先创建一个工厂 page(例如pages/[路由参数1]/[路由参数2].js
),接着getStaticPaths
填充路由参数,getStaticProps({ params })
根据参数请求不同数据,最后数据进入页面组件开始预渲染