VueRouter提供了一些路由钩子函数,允许开发者在不同的路由生命周期阶段执行自定义逻辑,从而实现更为灵活的路由控制。以下是VueRouter的一些常用路由钩子函数:
执行顺序:全局前置守卫 ➜ 组件内前置守卫 ➜ 路由独享的守卫 ➜ 路由自身的钩子函数 ➜ 组件内的后置钩子 ➜ 全局后置钩子。
VueRouter提供了多个路由钩子函数,用于在路由发生变化时执行某些操作或判断条件。
beforeRouteEnter(to, from, next):
在进入该路由前调用,但是此时该组件还未被创建。因此无法访问组件实例(this),可以通过next(vm => {})方式访问。
beforeRouteUpdate(to, from, next):
在当前路由更新但是该组件被复用时调用。可以访问组件实例(this),并在更新前后进行状态等的修改。
beforeRouteLeave(to, from, next):
在离开该路由前调用。可以访问组件实例(this),并进行一些清理操作或者询问用户是否离开当前页面。
这些路由钩子函数可以在单个路由配置中声明,也可以在全局路由守卫中使用。
全局路由守卫包括:
beforeEach(to, from, next)
在进入路由前调用,可以进行一些全局的权限验证或者登录验证等操作。
afterEach(to, from)
在路由完成后调用,可以进行一些全局的跟踪或者日志等操作。
路由钩子函数和全局路由守卫的执行顺序为:
全局前置守卫 ➜ 组件内前置守卫 ➜ 路由独享的守卫 ➜ 路由自身的钩子函数 ➜ 组件内的后置钩子 ➜ 全局后置钩子。
使用路由钩子函数和全局路由守卫可以更好地控制路由的行为,并进行一些额外的逻辑处理。
beforeEach:全局前置守卫,可以在路由跳转之前进行一些校验、权限判断等操作。该函数接受三个参数:to(即将跳转的目标路由对象)、from(当前的路由对象)和next(一个函数,必须调用该函数才能完成路由跳转)。例如:
router.beforeEach((to, from, next) => {
// 如果用户未登录,跳转到登录页
if (!isAuthenticated()) {
next({
path: '/login',
query: { redirect: to.fullPath } // 传递重定向参数
})
} else {
next()
}
})
afterEach:全局后置钩子,可以在路由跳转之后进行一些操作,如记录用户的浏览记录等。该函数只接受一个参数to,即目标路由对象。例如:
router.afterEach((to) => {
// 记录用户的浏览记录
addHistory(to.fullPath)
})
beforeEnter:路由独享的守卫,可以在路由进入之前进行一些校验操作。该函数接受三个参数:to、from和next。例如:
const userRoute = {
path: '/user',
component: User,
beforeEnter: (to, from, next) => {
if (!isAuthenticated()) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
}
}
beforeRouteUpdate:组件内路由更新前的钩子,可以在路由更新之前执行一些操作,如重新获取数据等。该函数接受两个参数:to和from。例如:
export default {
name: 'User',
beforeRouteUpdate (to, from, next) {
// 重新获取用户信息
this.getUserInfo(to.params.id)
.then(() => next())
.catch((err) => next(err))
},
methods: {
getUserInfo (id) {
return axios.get(`/api/user/${id}`)
.then((res) => {
this.userInfo = res.data
})
}
}
}
beforeRouteLeave:组件内路由离开前的钩子,可以在组件被销毁之前执行一些操作,如提示用户是否保存数据等。该函数接受两个参数:to、from和next。例如:
export default {
name: 'UserEdit',
beforeRouteLeave (to, from, next) {
if (this.isDirty()) {
// 如果用户修改了数据,提示是否保存
const result = window.confirm('是否保存修改内容?')
if (result) {
this.save()
.then(() => next())
.catch((err) => next(err))
} else {
next()
}
} else {
next()