在 Next.js 12 中,动态路由和参数传递主要通过文件系统路由(File-system Routing)实现。以下是详细步骤和示例:
一、创建动态路由
- 文件命名规则
在 pages
目录下创建文件名用 [参数名].js
格式的文件,例如:
pages/posts/[id].js // 单个参数
pages/[category]/[id].js // 多段参数
- 匹配的 URL 示例
/posts/123
→id: '123'
/news/456
→category: 'news', id: '456'
二、传递参数
- 使用
<Link>
组件导航
import Link from 'next/link';
// 传递单个参数
<Link href="/posts/123">Post 123</Link>
// 传递多个参数(自动拼接 URL)
<Link href="/news/456?author=John">Post 456</Link>
- 编程式导航(
useRouter
)
import { useRouter } from 'next/router';
function MyComponent() {
const router = useRouter();
const navigate = () => {
// 传递单个参数
router.push('/posts/123');
// 传递多个参数(URL 自动拼接)
router.push({
pathname: '/news/[id]',
query: { id: '456', author: 'John' },
});
};
return <button onClick={navigate}>跳转</button>;
}
三、获取参数
- 在页面组件中获取参数
使用useRouter
的query
对象:
import { useRouter } from 'next/router';
function Post() {
const router = useRouter();
const { id } = router.query; // 获取动态路由参数
const { author } = router.query; // 获取查询参数(如 ?author=John)
return <div>Post ID: {id}, Author: {author}</div>;
}
- 在
getStaticProps
或getServerSideProps
中获取参数
动态路由参数通过context.params
传递:
export async function getStaticProps(context) {
const { id } = context.params; // 获取动态路由参数
const res = await fetch(`https://api.example.com/posts/${id}`);
const post = await res.json();
return { props: { post } };
}
// 必须定义 getStaticPaths 来生成静态页面
export async function getStaticPaths() {
return {
paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
fallback: true, // 或 'blocking'
};
}
四、高级用法
- 可选参数(Optional Parameters)
使用双括号[[...参数名]]
格式:
pages/posts/[[...slug]].js
匹配的 URL:
/posts
→slug: undefined
/posts/123
→slug: ['123']
/posts/123/456
→slug: ['123', '456']
- 捕获所有路径(Catch-all Routes)
使用[...参数名].js
格式:
pages/posts/[...slug].js
匹配的 URL:
/posts/123
→slug: ['123']
/posts/123/456
→slug: ['123', '456']
五、注意事项
- fallback 模式
使用 getStaticPaths
时,若未预生成所有路径,需设置 fallback: true
或 'blocking'
,并在页面处理加载状态。
- 客户端渲染与服务器渲染
- 直接访问页面时(如刷新),参数会在首次渲染时存在。
- 客户端导航时,参数可能稍后加载,需处理
router.isReady
:
useEffect(() => {
if (router.isReady) {
const { id } = router.query;
}
}, [router.isReady]);
- 参数类型
所有参数均为字符串,需手动转换数字类型。
通过以上方法,你可以在 Next.js 12 中轻松实现动态路由、参数传递和获取。