除了使用
<router-link>声明式导航,Vue Router 还支持编程式导航,通过 JavaScript 代码控制路由跳转。
导航到不同的 URL,向 history 栈添加新记录。
this.$router.push('/home')
this.$router.push({ path: '/home' })
this.$router.push({ name: 'home' })
this.$router.push({
path: '/user',
query: {
name: '张三',
age: 25
}
})
this.$router.push({
name: 'user',
params: {
id: 123
}
})
this.$router.push({
name: 'user',
params: { id: 123 },
query: { tab: 'profile' }
})
this.$router.push('/home', () => {
console.log('导航完成')
}, (error) => {
console.error('导航失败', error)
})
this.$router.push('/home')
.then(() => {
console.log('导航完成')
})
.catch(error => {
console.error('导航失败', error)
})
替换当前路由,不会向 history 栈添加新记录。
this.$router.replace('/home')
this.$router.replace({ name: 'home' })
this.$router.replace({
path: '/user',
query: { id: 123 }
})
<router-link to="/home" replace>首页</router-link>
在 history 栈中前进或后退。
this.$router.go(1)
this.$router.go(-1)
this.$router.go(3)
this.$router.go(-2)
this.$router.go(100)
后退一步,等同于 router.go(-1)。
this.$router.back()
前进一步,等同于 router.go(1)。
this.$router.forward()
this.$router.push({
path: '/search',
query: {
q: 'vue',
page: 1,
size: 10
}
})
this.$router.push({
name: 'user',
params: { id: 123 }
})
注意:path 和 params 不能同时使用
this.$router.push({
path: '/user',
params: { id: 123 }
})
params 会被忽略,应该使用 name 或 path + query。
this.$router.push({
name: 'user',
params: { id: 123 },
query: { tab: 'profile' },
hash: '#section1'
})
this.$router.push(
'/home',
() => {
console.log('导航成功')
},
() => {
console.log('导航中止')
}
)
try {
await this.$router.push('/home')
console.log('导航成功')
} catch (error) {
if (error.name === 'NavigationDuplicated') {
console.log('重复导航')
} else {
console.error('导航失败', error)
}
}
this.$router.push('/login').catch(error => {
if (error.name !== 'NavigationDuplicated') {
console.error(error)
}
})
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(error => {
if (error.name !== 'NavigationDuplicated') {
return Promise.reject(error)
}
})
}
export default {
methods: {
async login() {
try {
await this.$store.dispatch('login', this.form)
const redirect = this.$route.query.redirect || '/'
this.$router.replace(redirect)
} catch (error) {
this.$message.error(error.message)
}
}
}
}
<template>
<button @click="goBack">返回</button>
</template>
<script>
export default {
methods: {
goBack() {
if (window.history.length > 1) {
this.$router.back()
} else {
this.$router.push('/')
}
}
}
}
</script>
export default {
methods: {
navigateTo(route) {
if (this.hasUnsavedChanges) {
const answer = window.confirm('有未保存的更改,确定离开?')
if (!answer) return
}
this.$router.push(route)
}
}
}
const routeData = this.$router.resolve({
name: 'user',
params: { id: 123 }
})
window.open(routeData.href, '_blank')
this.$router.go(0)
location.reload()
export default {
methods: {
switchTab(tab) {
this.$router.replace({
query: {
...this.$route.query,
tab
}
})
}
}
}
export default {
methods: {
async goToAdmin() {
if (!this.isLoggedIn) {
this.$router.push({
path: '/login',
query: { redirect: '/admin' }
})
return
}
this.$router.push('/admin')
}
}
}
export default {
methods: {
async navigateWithPermission(route) {
const hasPermission = await this.checkPermission(route)
if (hasPermission) {
this.$router.push(route)
} else {
this.$message.error('没有访问权限')
this.$router.push('/403')
}
}
}
}
export default {
data() {
return {
transitionName: 'slide-left'
}
},
watch: {
'$route'(to, from) {
const toDepth = to.path.split('/').length
const fromDepth = from.path.split('/').length
this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'
}
}
}
<transition :name="transitionName">
<router-view></router-view>
</transition>
编程式导航要点: