1. 核心概念重述

        在 Vue.js 应用中,除了使用 <router-link> 进行声明式路由跳转外,还可以通过调用路由器实例的方法实现编程式导航。这种方式允许我们在逻辑代码中动态控制页面跳转,适用于按钮点击、表单提交、权限判断等场景。

2. 编程式导航方法概览

方法 对应声明式 功能描述
router.push() <router-link :to="..."> 导航到新路径,并在浏览器历史中添加一条记录
router.replace() <router-link :to="..." replace> 导航并替换当前历史记录,不会保留原页面
router.go(n) —— 在历史记录中前进或后退 n 步

3. 详解三大导航方法

 router.push(path)

用于导航到新的 URL,并将该记录添加到浏览器的 history 栈中。

使用方式:
// 字符串路径
router.push('/users/eduardo')

// 路径对象
router.push({ path: '/users/eduardo' })

// 命名路由 + 参数(推荐)
router.push({ name: 'user', params: { username: 'eduardo' } })

// 查询参数
router.push({ path: '/register', query: { plan: 'private' } }) // /register?plan=private

// Hash 片段
router.push({ path: '/about', hash: '#team' }) // /about#team

⚠️ 注意:如果提供了 path,则 params 会被忽略。必须使用 name 或手动拼接路径来传递参数。

const username = 'eduardo'

// ❌ 错误:path 与 params 不兼容
router.push({ path: '/user', params: { username } }) // 结果为 /user

// ✅ 正确:使用 name
router.push({ name: 'user', params: { username } }) // /user/eduardo

// ✅ 正确:手写完整 path(需自行编码)
router.push({ path: `/user/${username}` })
返回 Promise
router.push({ name: 'user', params: { username: 'eduardo' } })
  .then(() => {
    console.log('导航成功')
  })
  .catch(err => {
    if (err.name !== 'NavigationFailure') {
      console.error('导航失败:', err)
    }
  })

这使得我们可以处理导航异常(如重复导航、权限不足等)。

✅ router.replace(path)

push 类似,但不向 history 添加新记录,而是替换当前条目

使用方式:
// 方式一:直接调用 replace
router.replace('/home')

// 方式二:在 push 中设置 replace: true
router.push({ path: '/home', replace: true })

应用场景:登录后跳转首页,用户按“返回”不应回到登录页。

✅ router.go(n)

在浏览器历史栈中移动指定步数。

router.go(1)   // 前进一步,相当于 forward()
router.go(-1)  // 后退一步,相当于 back()
router.go(3)   // 前进三步
router.go(-100)// 若历史不足,则静默失败

        Vue Router 模拟了 window.history.go(n) 的行为,无论使用何种 history 模式(hash、history、abstract),均可正常工作。

4. 在组件中的访问方式

选项式 API(Options API)

通过 this.$router 访问:

<script>
export default {
  methods: {
    goToUser() {
      this.$router.push({ name: 'user', params: { username: 'alice' } })
    },
    goBack() {
      this.$router.go(-1)
    }
  }
}
</script>

组合式 API(Composition API)

使用 useRouter() 钩子:

<script setup>
import { useRouter } from 'vue-router'

const router = useRouter()

function navigateToHome() {
  router.push('/')
}

function replaceAndGo() {
  router.replace({ path: '/dashboard', query: { from: 'login' } })
}
</script>

5. 参数传递规则总结

类型 写法 示例 URL 输出
path 字符串 router.push('/path') /user/eduardo /user/eduardo
path + query { path: '', query: {} } { path: '/search', query: { q: 'vue' } } /search?q=vue
path + hash { path: '', hash: '' } { path: '/info', hash: '#top' } /info#top
name + params { name: '', params: {} } { name: 'user', params: { username: 'bob' } } /user/bob(需路由定义支持)
❌ path + params 不支持 { path: '/user', params: { id: 1 } } /user(params 被忽略)

💡 推荐:优先使用 命名路由 + params,可自动进行 URL 编码,避免手动处理特殊字符。

6. 路由跳转对比图表示意

7. 常见问题与最佳实践

❓为什么 params 在 path 下无效?

        因为 params 只有在通过 name 匹配路由时才生效。Vue Router 需要根据路由名称查找对应的模式(如 /user/:username)才能正确填充参数。

✅ 正解:

router.push({ name: 'user', params: { username: 'john' } })

❌ 错误:

router.push({ path: '/user', params: { username: 'john' } }) // params 被丢弃

🛠️ 如何安全地拼接带参数的路径?

使用模板字符串并配合 encodeURIComponent

const username = '张三'
router.push(`/user/${encodeURIComponent(username)}`)

或者更推荐的方式是使用 name params,由框架自动编码。

✅ 编程式导航的优势

  • 条件跳转(如登录验证)

  • 表单提交后跳转

  • 异常处理后跳转错误页

  • 动态构建目标路径

  • 支持 Promise 处理导航结果

8. 总结归纳

方法 是否新增 history 记录 是否可返回 典型用途
push() ✅ 是 ✅ 可返回 正常跳转
replace() ❌ 否 ❌ 不可返回 登录跳转、防止回退
go(n) —— 控制前进后退 自定义导航逻辑

9. 知识点

  • $router 与 useRouter():在组件中访问路由器实例的方式,选项式用 this.$router,组合式用 useRouter()

  • 命名路由与 params:通过 name params 实现安全参数传递,避免手动编码 URL。

  • history 操作机制pushreplacego 分别对应浏览器 history 的三种操作,模拟其行为且跨模式兼容。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐