Next.js 中,你可以通过多种方式实现编程式导航(即通过代码而非 <Link>
组件跳转页面)。以下是完整的实现方法:
1. 使用 useRouter
Hook(函数组件)
这是最常用的方法,适用于函数组件:
import { useRouter } from 'next/router';function MyComponent() {const router = useRouter();const handleClick = () => {// 基本跳转router.push('/target-page');// 带查询参数router.push({pathname: '/target-page',query: { id: 123 },});// 替换当前历史记录而不是添加新记录// router.replace('/target-page');};return (<button onClick={handleClick}>跳转到目标页</button>);
}
2. 使用 withRouter
HOC(类组件)
如果你使用类组件,可以使用 withRouter
高阶组件:
import { withRouter } from 'next/router';class MyComponent extends React.Component {handleClick = () => {this.props.router.push('/target-page');};render() {return (<button onClick={this.handleClick}>跳转到目标页</button>);}
}export default withRouter(MyComponent);
3. 直接使用 Router
对象
不需要组件时可以直接使用 Router 对象:
import Router from 'next/router';// 在任何地方使用
Router.push('/target-page');
4. 高级跳转选项
带查询参数和 hash
router.push({pathname: '/post',query: { id: '123' }, // 查询参数hash: 'comments', // hash 片段
});
替换当前历史记录
router.replace('/target-page'); // 不会在历史记录中添加新条目
预加载页面
// 预加载目标页面资源
Router.prefetch('/target-page');
5. 路由事件监听
import Router from 'next/router';// 路由变化开始
Router.events.on('routeChangeStart', (url) => {console.log('路由开始变化:', url);
});// 路由变化完成
Router.events.on('routeChangeComplete', (url) => {console.log('路由变化完成:', url);
});// 路由变化错误
Router.events.on('routeChangeError', (err, url) => {console.log('路由变化错误:', err, url);
});// 取消监听
Router.events.off('routeChangeStart', handler);
6. 动态路由跳转
对于动态路由页面:
// 跳转到 /post/[pid].js
router.push('/post/123');// 或者使用对象形式
router.push({pathname: '/post/[pid]',query: { pid: '123' },
});
7. 获取路由信息
const router = useRouter();// 获取当前路径
console.log(router.pathname); // /current-path// 获取查询参数
console.log(router.query); // { id: '123' }
8. 等待页面加载完成
const handleClick = async () => {await router.push('/target-page');// 这里可以执行跳转后的操作console.log('页面跳转完成');
};
注意事项
-
浅路由:使用
shallow: true
可以在不运行数据获取方法的情况下改变 URLrouter.push('/?counter=1', undefined, { shallow: true });
-
外部链接:对于外部网站,使用
window.location
或<a>
标签 -
性能:对于重要页面,考虑使用
prefetch
提高用户体验 -
滚动行为:默认会滚动到顶部,可以通过
scroll: false
禁用router.push('/target-page', undefined, { scroll: false });
完整示例
import { useRouter } from 'next/router';
import { useEffect } from 'react';export default function Page() {const router = useRouter();useEffect(() => {// 预加载可能访问的页面router.prefetch('/dashboard');}, []);const handleLogin = async () => {await fetch('/api/login', { method: 'POST' });router.push({pathname: '/dashboard',query: { from: 'login' },});};return (<div><h1>欢迎页</h1><button onClick={handleLogin}>登录并跳转</button><button onClick={() => router.replace('/guest')}>游客访问</button></div>);
}
这些方法覆盖了 Next.js 中编程式导航的所有常见用例,你可以根据具体需求选择最适合的方式。