作用:vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的。
参数-例如:
beforeEach(to,from,next){
//to 即将要进入的目标路由对象
//from 当前导航要离开的路由对象
//next() //这里要使用next放行 否则无法创建实例
}
钩子函数的执行顺序:
Vue-Router
前置路由守卫会调用store里面的getUserInfo方法获取用户信息,存储在vuex里面,然后BaseHeader会通过计算属性,自动计算user的值,如果获取了用户信息,会就把登录、注册按钮变为用户的头像 。
前置路由守卫router.beforeEach()
:在初始化和每一次路由切换之前调用函数,控制用户信息的获取。
当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中。
//注册
const router = createRouter({ ... })
//全局守卫
router.beforeEach((to, from, next)=> {
// 判断是否登录
if(sessionstorage.getItem("isLogin") == "1") {
next()
}else {
// 如果没有登录,但是跳转登录页面也放行
if(to.name == 'login') {
next()
}else {
// 如果没有登录,也不是去登录页,就拦截,让它跳转登录页
next('/login')
}
}
);
全局解析守卫router.beforeResolve()
:和 router.beforeEach 类似,因为它在 每次导航时都会触发,但是确保在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被正确调用。
是获取数据或执行任何其他操作(如果用户无法进入页面时你希望避免执行的操作)的理想位置。
router.beforeResolve(async to => {
if (to.meta.requiresCamera) {
try {
await askForCameraPermission()
} catch (error) {
if (error instanceof NotAllowedError) {
// ... 处理错误,然后取消导航
return false
} else {
// 意料之外的错误,取消导航并把错误传给全局处理器
throw error
}
}
}
})
全局后置钩子router.afterEach()
:在离开路由的时候执行。
和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身,它们对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。
router.afterEach((to,from,next)=>{
if(to.meta.title){
document.title = to.meta.title //修改网页的title
}else{
document.title = "vue_test"
}
})
beforeEnter()
:只在进入路由时触发,不会在 params、query 或 hash 改变时触发。在配置页面,单独给路由配置的守卫
const routes = [{
path: '/users/:id',
component: UserDetails,
beforeEnter: (to, from) => {
// reject the navigation
return false
},
},]
也可以将一个函数数组传递给 beforeEnter,这在为不同的路由重用守卫时很有用:
function removeQueryParams(to) {
if (Object.keys(to.query).length)
return { path: to.path, query: {}, hash: to.hash }
}
function removeHash(to) {
if (to.hash) return { path: to.path, query: to.query, hash: '' }
}
const routes = [
{
path: '/users/:id',
component: UserDetails,
beforeEnter: [removeQueryParams, removeHash],
},
{
path: '/about',
component: UserDetails,
beforeEnter: [removeQueryParams],
},
]
写在vue文件里,与methods同级
beforeRouteEnter(){next()}:进入路由之前,组件实例未渲染,所以此时this无法调用。
注意:beforeRouteEnter 是支持给 next 传递回调的唯一守卫。
this
!beforeRouteUpdate():同一页面刷新不同数据时调用。
/users/:id
,在 /users/1
和 /users/2
之间跳转的时候UserDetails
组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。this
beforeRouteLeave():离开当前路由页面时调用。
beforeRouteUpdate
一样,它可以访问组件实例 this
//进入守卫,通过路由规则,进入该组件时被调用
beforeRouteEnter(to,from,next){
if(to.meta.isAuth){//判断当前路由是否需要进行权限控制
if(localStorage.getItem('school') == "aiguigu"){
next()//执行
}else{
alert('暂无权限查看')
}
}else{
next()
}
},
//离开守卫,通过路由规则,离开该组件时被调用
beforeRouteLeave(to,from,next){
},