router.push是入栈操作,向历史栈添加新记录,用户可返回;router.replace是替换操作,覆盖当前栈顶页面,用户无法返回原页。

router.push 和 router.replace 都是 Vue Router 提供的编程式导航方法,核心区别在于是否向浏览器历史栈新增记录——push 是“加一页”,replace 是“换一页”。选错方法,轻则返回逻辑错乱,重则用户误操作、重复提交或直接退出应用。
push:保留返回路径,适合需要回退的跳转
每次调用 router.push,都会在 history 栈中新增一条记录。用户点击返回按钮,就能逐层退回上一个页面。
- 适用场景:页面间正常流转,比如从商品列表 → 商品详情 → 订单确认 → 支付页
- 注意点:同一页面被 push 多次,就会生成多条独立记录。例如连续三次跳转到 /pay,返回时就得点三次才能回到列表页
- 常见隐患:在 onShow、onLoad 或未防抖的点击事件里反复执行 push,容易造成栈冗余
replace:覆盖当前页,适合无痕跳转
router.replace 不新增记录,而是直接用新页面替换掉当前栈顶项。用户点返回,会跳过被 replace 的页面,回到它之前的那一页。
- 适用场景:表单提交成功后跳转结果页、登录成功后跳首页、404/权限拦截后强制跳转
- 关键效果:防止用户刷新或后退再次触发提交;避免登录页残留导致返回即退出
- 典型错误:在登录流程中先 push 登录页,再 replace 回首页——登录页被抹除,首页变成栈顶,返回就退出应用
怎么选?看业务是否需要“可返回”
判断标准很简单:用户完成当前操作后,是否应该允许他按返回键回到这一页?
- 要返回 → 用 push(如查看详情、进入设置)
- 不返回 → 用 replace(如提交成功、登录完成、错误跳转)
- 不确定 → 先用 replace,后续根据用户反馈再调整。replace 更安全,不会污染历史栈
补充提醒:传参和错误处理不能少
两者都支持对象写法传参,推荐用 name + params(需路由配置 props: true),避免 path 模式下 params 失效:
- 正确:router.push({ name: 'OrderDetail', params: { id: '123' } })
- 错误:router.push({ path: '/order', params: { id: '123' } }) —— params 不会生效
- 异常捕获:router.push('/admin').catch(err => console.warn('跳转失败:', err)),尤其在路由守卫或异步组件加载失败时有用











