
本文详解如何使用 next/link 结合 URL 查询参数,在 Next.js 中安全、规范地将数据(如 title、desc)传递至新页面,并在目标页面中读取,适用于新标签页跳转场景,避免滥用客户端路由或破坏服务端渲染逻辑。
本文详解如何使用 next/link 结合 URL 查询参数,在 Next.js 中安全、规范地将数据(如 title、desc)传递至新页面,并在目标页面中读取,适用于新标签页跳转场景,避免滥用客户端路由或破坏服务端渲染逻辑。
在 Next.js 中,组件间无法像 Flutter 的 MaterialPageRoute(builder: ...) 那样直接以 props 形式实例化并传参——因为页面是服务端渲染(SSR)或静态生成(SSG)的独立路由单元,不具备“运行时构造组件”的客户端导航语义。但你可以通过 URL 查询参数(query string) 实现等效效果:既保持路由语义清晰、SEO 友好,又兼容新标签页(target="_blank")和客户端导航。
✅ 推荐方案:使用 next/link + router.query
该方式完全基于 Next.js 官方路由机制,无需混用 next/navigation(App Router)与 Pages Router 的 API,也不推荐在 Pages Router 项目中强行引入 useRouter from next/navigation(二者不兼容)。以下示例基于稳定的 Pages Router(即 pages/ 目录结构),这也是当前问题上下文所适用的场景。
? 发送页:构造带查询参数的链接
// pages/sender.tsx
import Link from 'next/link';
const SenderPage = () => {
const example = 'Title Example';
const example2 = 'Description Example';
return (
<Link
href={{
pathname: '/page', // ✅ 替换为你的目标页面路径(如 '/product')
query: { title: example, desc: example2 },
}}
passHref
>
<a
target="_blank"
rel="noopener noreferrer"
className="text-blue-600 hover:underline"
>
Open Page in New Tab
</a>
</Link>
);
};
export default SenderPage;⚠️ 注意事项:
- passHref 是必需的:它确保 <a> 标签获得正确的 href 属性(如 /page?title=...&desc=...),对可访问性(a11y)、SEO 和浏览器原生行为至关重要;
- target="_blank" 必须搭配 rel="noopener noreferrer",防止新页面通过 window.opener 访问原始页面,规避安全风险;
- pathname 必须是 Next.js 中已定义的有效页面路径(对应 pages/page.tsx),不可为任意 React 组件路径。
? 接收页:通过 useRouter 解析查询参数
// pages/page.tsx
import { useRouter } from 'next/router';
const Page = () => {
const router = useRouter();
// ✅ router.query 是一个字符串字典(即使单值也返回字符串数组)
// 使用可选链 + 类型断言提升健壮性
const title = Array.isArray(router.query.title)
? router.query.title[0]
: (router.query.title as string) || 'Untitled';
const desc = Array.isArray(router.query.desc)
? router.query.desc[0]
: (router.query.desc as string) || 'No description';
// ⏳ 路由未就绪时显示加载态(可选)
if (router.isFallback) {
return <div>Loading...</div>;
}
return (
<div className="p-6 max-w-2xl mx-auto">
<h1 className="text-3xl font-bold text-gray-800">{title}</h1>
<p className="mt-2 text-gray-600">{desc}</p>
{/* 其他业务内容 */}
</div>
);
};
export default Page;? 提示:
- router.query 在服务端首次渲染时即包含解析后的参数(SSR 友好);
- 若需强类型支持,建议配合 Zod 或自定义 hook 做参数校验(例如确保 title 为非空字符串);
- 对敏感信息(如 token、用户 ID),切勿通过 query 传递——应改用 POST 表单、Cookie、或服务端会话存储。
❌ 常见误区澄清
- 不要混用 next/navigation 与 Pages Router:next/navigation 专用于 App Router(app/ 目录),而 next/router 才是 Pages Router 的标准 API。两者不可互换,否则会导致运行时错误或 hydration mismatch。
- 不推荐 window.open() + useState 传参:浏览器新开标签页无法共享内存状态,useState 数据不会跨页面传递。
- 避免 as 属性伪造 URL:<Link href="/api/fake" as="/page?title=..."> 已废弃且不可靠,应始终使用 pathname + query 显式声明。
✅ 总结
| 场景 | 推荐方式 |
|---|---|
| Pages Router(pages/)中跳转并传参 | next/link + pathname/query + useRouter |
| 新标签页打开 | <a target="_blank" rel="noopener noreferrer"> 包裹 Link |
| 类型安全 & 参数校验 | 在接收页对 router.query 做解构+默认值+数组防护 |
| 敏感数据传递 | 改用服务端重定向(res.redirect())、数据库临时记录或 JWT Token |
通过这一模式,你既能复现 Flutter 中“构造页面并传参”的开发体验,又能完全遵循 Next.js 的路由哲学——URL 即状态,链接即接口。










