目录
编程式的导航
除了使用 <router-link>
创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
router.push(location, onComplete?, onAbort?)
想要导航到不同的 URL,则使用 router.push
方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。
当你点击 <router-link>
时,这个方法会在内部调用,所以说,点击 <router-link :to="...">
等同于调用 router.push(...)
。
声明式 | 编程式 |
---|---|
<router-link :to="..."> | router.push(...) |
该方法的参数可以是一个字符串路径,或者一个描述地址的对象。
<template>
<div id="app">
<a @click="linkToHome">首页</a> |
<a @click="linkToAbout">关于</a>
<router-view/>
<div>我是版权信息</div>
</div>
</template>
<script>
export default {
name: 'App',
methods: {
linkToHome() {
// 字符串
this.$router.push('home')
// 对象
// this.$router.push({ path: 'home' })
// 命名的路由
// this.$router.push({ name: 'goods', params: { id: 3 }})
// 带查询参数,变成 /goods?type=1
// this.$router.push({ path: 'goods', query: { type: '1' }})
},
linkToAbout() {
this.$router.push('about')
}
}
}
</script>
注意:如果提供了
path
,params
会被忽略:// 这里的 params 不生效 this.$router.push({ path: 'goods', params: { id: 3 }})
同样的规则也适用于 router-link
组件的 to
属性。
router.replace(location, onComplete?, onAbort?)
跟 router.push
很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。
声明式 | 编程式 |
---|---|
<router-link :to="..." replace> | router.replace(...) |
router.go(n)
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)
。
// 在浏览器记录中前进一步,等同于 history.forward()
this.$router.go(1)
// 后退一步记录,等同于 history.back()
this.$router.go(-1)
// 前进 3 步记录
this.$router.go(3)
// 如果 history 记录不够用,那就默默地失败呗
this.$router.go(-100)
this.$router.go(100)
有时候会存在重复点击路由报错的问题: Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location: "/home".
虽然这个报错并不影响程序的正常运行,但是依然让人感到很不爽。
造成这个报错的原因,大多是说因为 Vue-Router 版本的原因,但是我尝试更换了不同版本,但是依然没有得到缓解。
解决方法,在 src/router/index.js
文件中添加一段代码即可:
// 解决重复点击路由报错的BUG
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch((err) => err)
}
const originalReplace = VueRouter.prototype.replace
VueRouter.prototype.replace = function replace(location) {
return originalReplace.call(this, location).catch((err) => err)
}