Vue2.0 Vue路由 全局前置路由守卫

知道了全新的俩个生命周期钩子还有

跟路由有关的第一个知识点: 路由守卫

这个东西很重要,开发当中用的很多

御前侍卫:保护君王的安全

我们路由守卫和御前侍卫干的活是一样的,只不过:

路由守卫:保护路由的安全(权限)。

有些时候不是所有的导航项不是可以随便点击的

你得符合了一些要求才可以点

提出要求

homeAbout随便点击,但是NewsMessage只能是有schoolbilibili的才可以访问

要求是点击News或者Message的时候帮我校验一下school是不是bilibili。是就可以访问下面的内容,如果不是就不能访问

解决要求

这事得跟路由器商量商量:

就是以后有人访问的这个路由是/home/news就让路由帮我们做一件事,你去localStorage中的那个school你帮我读取出来看看是不是bilibili,如果是,组件正常呈现;如果不是就别呈现了。所以

router > index.js

//我让每一个路由都有名字
export default new VueRouter({
    routes:[
        //想在哪里进行二次跳转,就写在个配置里(用children)
        {
            name: 'zhuye',
            path: '/home',
            component: Home,
            children:[
                {
                    name: 'xinxi',
                    path: 'news',//注意路由底层给你加了'/'如果自己加'/'有可能还显示不出效果
                    component:News,
                },
                {
                    name: 'xiaoxi',
                    path: 'message',
                    component: Message,
                    children:[
                        {
                            name: 'xiangqing',
                            path: 'detail/:id/:name',
                            component: Detail,

                            props($route){
                                return {id: $route.query.id, name: $route.query.name}
                            }
                        }
                    ]
                }
            ]
        },
        {
            name:'guanyu',
            path: '/about',
            component: About
        }
    ]
})

AboutHome都是一级路由,但是你这样写就瞬间把路由器暴露出去了(export default ...)所以你先要接住路由器(const router)

const router = new VueRouter({
    routes:[...]
})
//暴露之前跟它商量商量
//加一个路由守卫
//借助自身身上特别的API了,叫做'beforeEach'
//before:  ...之前
//Each:每一个;每一次;每一人
//我们要做的就是每一次切换之前,都会帮你调用一个。。函数
//这个有点像setTimeout,我调setTimeout是指定一个定时器的回调函数,那我调beforEach的回调函数的目的是指定路由每次切换时的一次回调函数就是()=>{}这个
//全局前置路由守卫--初始化的时候被调用,每次调用路由切换之前被调用
router.beforeEach(()=>{
	console.log('@')//测试
})

export default router

只要你形成路由的跳转(A -> B),那么router.beforEach中的函数就会被调用的,而且这是在切换进行之前调用的

你点击Home组件内容没出来,待会儿再说

但是只要你切换,它就调beforeEach里面的方法

为什么什么都没有,就要研究里面的参数了:

  • to(字面意思:你要去哪)
  • from(字面意思:你来自于哪)

输出to,from

router.beforeEach((to,from)=>{
	console.log('to=',to,'from=',from)//测试
})

一上来的这一次不用关心(因为起点终点是一致的):

to= {name: null, meta: {…}, path: '/', hash: '', query: {…}, …}
from= {name: null, meta: {…}, path: '/', hash: '', query: {…}, …}

我们点击(切换)到home:

to= {name: 'zhuye', meta: {…}, path: '/home', hash: '', query: {…}, …}
from= {name: null, meta: {…}, path: '/', hash: '', query: {…}, …}

把你要去的目标路由信息都给你了

还是去不了,因为就这里的路由守卫的内容 把你所有的都给拦住了

这时next就有用了

  • next(放行)

你没有说放行,它不敢往下走

router.beforeEach((to,from,next)=>{
	console.log('to=',to,'from=',from)//测试
    next()
})

你这么一写就可以了


接下来就只要判断你什么时候放行,什么时候不放行就可以了

动态决定是否放行

第一步:

router.beforeEach((to,from,next)=>{
	console.log('to=',to,'from=',from)//测试
    if(localStorage.getItem('school')==='bilibili'){
        next()
    }
})

如果没有school-bilibili是连homeabout都不能看,但我的需求是这俩个随意都能看,你得问问人家,你去哪,如果去home和about我不管你,只要你去news和message我就要管你

第二步:

你得判断to里面的path或者name:

router.beforeEach((to,from,next)=>{
	console.log('to=',to,'from=',from)//测试
    if(to.path === '/home/news' || to.path === '/home/message'){
        if(localStorage.getItem('school')==='bilibili'){
        	next()
    	}else{
            alert('学校名不对,无权限查看')
        }
    }else{
        next()
    }
})

路由前如果拦截,你会发现路径是不变的

用名字决定

router.beforeEach((to,from,next)=>{
	console.log('to=',to,'from=',from)//测试
    if(to.name === 'xinxi' || to.name === 'xiaoxi'){
        if(localStorage.getItem('school')==='bilibili'){
        	next()
    	}else{
            alert('学校名不对,无权限查看')
        }
    }else{
        next()
    }
})

配置自定义属性

 if(to.name === 'xinxi' || to.name === 'xiaoxi')

是不是觉得这段很鸡肋,如果要写12个100个是不是裂开?

能否在路由的配置项里面加一个配置来判断?

在路由的配置项里面,一个一个配置项都是写好的

我们先看this.$router:

mounted(){
    console.log('%%%',this.$route)
}
%% 
{name: 'xinxi', meta: {…}, path: '/home/news', hash: '', query: {…}, …}
    fullPath: "/home/news"
    hash: ""
    matched: (2) [{…}, {…}]
    meta: {}
    name: "xinxi"
    params: {}
    path: "/home/news"
    query: {}
    [[Prototype]]: Object	

加一点自己独有的配置,怎么放?告诉你: 往meta里面放

我们管这个meta路由元信息

{
    name:'guanyu',
    path: '/about',
    component: About,
    meta:{
        //这里可以不写,拿不出来就是undefined,undefined说明是假
        isAuth: false//isAuth:是否授权
    }
}

isAuth谁需要权限的校验,我就放在谁那

这里是NewsMessage需要,所以:

{
     name: 'xinxi',
     path: 'news',//注意路由底层给你加了'/'如果自己加'/'有可能还显示不出效果
     component:News,
     meta:{isAuth:true}
 },
 {
     name: 'xiaoxi',
     path: 'message',
     component: Message,
     children:[
         {
             name: 'xiangqing',
             path: 'detail/:id/:name',
             component: Detail,
            props($route){
                return {id: $route.query.id, name: $route.query.name}
            }
        }
    ],
    meta:{isAuth:true}
}

那么路由守卫里面就可以这么写:

router.beforeEach((to,from,next)=>{
	console.log('to=',to,'from=',from)//测试
    if(to.meta.isAuth){//判断是否鉴权
        if(localStorage.getItem('school')==='bilibili'){
        	next()
    	}else{
            alert('学校名不对,无权限查看')
        }
    }else{
        next()
    }
})

这就是前置路由守卫,切换前被调用

全局后置路由守卫


版权声明:本文为yasinawolaopo原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。