初级路由守卫
路由守卫的类型
Vue 提供了三种类型的路由守卫,分别是全局前置守卫、路由独享守卫和组件内守卫。它们分别对应了不同的场景和应用。
全局前置守卫
router.beforeEach((to, from, next) => {
// to 表示要跳转的目标路由
// from 表示当前的路由
// next 表示继续执行跳转,如果传入了参数则表示中止跳转并跳转到指定路由
// 执行你的逻辑,例如验证是否登录
if (!isLogin && to.path !== '/login') {
next('/login')
} else {
next()
}
})
上面的例子中,我们判断用户是否登录,如果未登录且目标路由不是 /login,则跳转到登录页。否则,继续执行路由跳转。
路由独享守卫
路由独享守卫是针对某个路由单独设置的守卫。我们可以在路由配置中设置 beforeEnter 字段来定义路由独享守卫。
const router = new VueRouter({
routes: [
{
path: '/user/:id',
component: User,
beforeEnter: (to, from, next) => {
// 执行你的逻辑,例如判断用户是否有权限访问该页面
if (!hasPermission(to.params.id)) {
next('/403')
} else {
next()
}
}
}
]
})
上面的例子中,我们为 /user/:id 路由单独设置了一个路由独享守卫,用来判断用户是否有权限访问该页面。如果用户没有权限,则跳转到 /403 页面。
组件内守卫
组件内守卫是在组件内部使用的守卫,可以在组件内部控制路由跳转的行为。组件内守卫包括 beforeRouteEnter、beforeRouteUpdate 和 beforeRouteLeave 三种类型。
export default {
beforeRouteEnter(to, from, next) {
// 无法访问组件实例
next(vm => {
// 访问组件实例
vm.fetchData()
})
},
methods: {
fetchData() {
// 执行你的逻辑,例如加载数据
}
}
}
在上面的代码中,我们通过在 next 方法中传递一个回调函数来访问组件实例,并调用组件的 fetchData 方法来加载数据。下面分别介绍一下这三种组件内守卫的使用方法。
beforeRouteEnter
beforeRouteEnter 钩子在组件被创建前调用,因此在这个钩子中无法访问到组件实例。
export default {
beforeRouteEnter(to, from, next) {
// 无法访问组件实例
next(vm => {
// 访问组件实例
vm.fetchData()
})
},
methods: {
fetchData() {
// 执行你的逻辑,例如加载数据
}
}
}
beforeRouteUpdate
beforeRouteUpdate 钩子在当前路由更新时调用,可以用来响应路由参数的变化。该钩子函数接收三个参数,分别为 to、from 和 next。
export default {
beforeRouteUpdate(to, from, next) {
// 执行你的逻辑,例如更新组件的数据
this.loadData(to.params.id)
next()
},
methods: {
loadData(id) {
// 执行你的逻辑,例如加载数据
}
}
}
在上面的代码中,我们在 beforeRouteUpdate 钩子中更新了组件的数据,以响应路由参数的变化。
beforeRouteLeave
beforeRouteLeave 钩子在当前路由离开时调用,可以用来提示用户保存未保存的数据或者进行其他的清理工作。该钩子函数接收三个参数,分别为 to、from 和 next。
export default {
beforeRouteLeave(to, from, next) {
if (this.dirty) {
if (confirm('您有未保存的数据,确定要离开吗?')) {
next()
} else {
next(false)
}
} else {
next()
}
},
data() {
return {
dirty: false
}
}
}
在上面的代码中,我们判断了组件中是否有未保存的数据,如果有则弹出确认对话框,询问用户是否要离开。如果用户点击了“确定”按钮,则继续路由跳转。如果用户点击了“取消”按钮,则中止路由跳转。如果组件中没有未保存的数据,则直接继续路由跳转。
总结
Vue 的路由守卫的使用方法,包括全局前置守卫、路由独享守卫和组件内守卫。通过使用路由守卫,我们可以实现登录验证、权限控制、异步加载数据等功能。
常见的相关面试题
Vue 的路由守卫有哪些类型?
Vue 的路由守卫分为全局前置守卫、全局后置守卫、路由独享守卫和组件内守卫四种类型。
全局前置守卫和路由独享守卫有什么区别?
- 全局前置守卫是注册在 Vue Router 实例上的,会在任意路由跳转前被调用,用于进行全局的登录验证和权限控制等操作。
- 路由独享守卫是在路由配置时通过 beforeEnter 字段定义的,仅对该路由有效,用于进行该路由的特定验证和处理。
如何在组件内定义路由守卫?
- 在组件内定义路由守卫,需要使用以下三个钩子函数:beforeRouteEnter、beforeRouteUpdate 和beforeRouteLeave
- beforeRouteEnter 钩子在组件被创建前调用,无法访问组件实例,需要通过 next方法传递一个回调函数来访问组件实例。
- beforeRouteUpdate 钩子在当前路由更新时调用,可以用来响应路由参数的变化。
- beforeRouteLeave 钩子在当前路由离开时调用,可以用来提示用户保存未保存的数据或进行其他的清理工作。
路由守卫的使用场景有哪些?
- 登录验证:通过全局前置守卫来检查用户是否已经登录,并在未登录时重定向到登录页。
- 权限控制:通过路由独享守卫来检查用户是否有权限访问某个路由,并在没有权限时显示错误信息或重定向到错误页面。
- 异步加载数据:通过组件内守卫的 beforeRouteEnter 钩子来异步加载数据,避免数据在组件创建前加载完成。
- 提示保存未保存的数据:通过组件内守卫的 beforeRouteLeave 钩子来提示用户保存未保存的数据或进行其他的清理工作。
Vue2和Vue3的路由守卫
Vue 2 和 Vue 3 都支持路由守卫,使用方式也大致相同。不过在 Vue 3 中,Vue Router 已经被重新设计为一个插件,因此在使用路由守卫时,需要在项目中安装 Vue Router 插件,而不是像 Vue 2 一样直接在 Vue 实例中引入。
Vue 2 中的路由守卫包括全局前置守卫、全局后置守卫、路由独享守卫和组件内守卫四种类型,使用方式类似于上面代码中的示例。而在 Vue 3 中,路由守卫的类型和使用方式也基本相同,只是需要将路由守卫注册到 Vue Router 插件实例上。
需要注意的是,由于 Vue 3 中的一些语法和 API 发生了变化,因此在编写 Vue 3 中的路由守卫时,需要略作调整。例如,在 Vue 3 中,组件内的路由守卫的使用方式和 Vue 2 中略有不同,需要使用 setup()
函数来定义路由守卫。同时,beforeRouteEnter 钩子函数的用法也有所不同,需要使用 next(vm => {})
传递一个回调函数来访问组件实例。