解密!Vue路由守卫的使用

什么是路由

对路由这个概念,可能有些人并不很理解,但是路由器大家应该都不陌生。我们可以先来了解一下路由器是什么。路由器现在基本上家家都会有,大家是否好奇过它名字的来源?其实搞懂了路由器名字的来历,我们就可以搞懂什么是路由了,如下图:

图片

图片

上面两张图分别介绍了路由器和路由的功能。首先他们都是用来进行请求分发,并且都是根据地址进行分发的。在进行分发时,只要匹配到了地址就会将请求指向该地址对应的资源。只不过路由器分发的是网络资源,而Vue路由则是分页指向不同的请求页面,但本质上他们的功能是类似的。

什么是路由守卫

路由守卫,顾名思义就是守护每个请求在路由到目标资源时,检查该请求是否合法。如上图所示,对左侧的/test1请求,理论上可以匹配到右侧的 /test1 资源,但有时右侧的 /test1 需要权限才可以访问。所以现在就算路由的地址正确,但因为有路由守卫的功能,可能会因为未认证或者权限不够等问题,我们也不能访问,这就是路由守卫。所以路由守卫其实就是对一些请求进行校验和过滤的防护检查机制。

路由守卫的分类

1. 守卫分类

我们先来看看路由守卫具体有哪些分类吧。

1.1 全局前置守卫(重要)

全局前置守卫会在用户发起请求触发导航时被创建,并且时刻处于等待中,等待着请求的到来。

//创建路由对象
const router = new VueRouter({ ... })
/**
 * 调用全局前置守卫
 * 参数1: to: 跳转的目标路由对象
 * 参数2: from: 当前要离开的路由
 * 参数3: next函数: 类似于Java中过滤器的放行,如果校验结束之后放行,让请求通过
 */
router.beforeEach((to, from, next) => {// ...})


/**
 * 案例使用
 */
 router.beforeEach((to, from, next) => {
     if (to.name !== 'Login' && !isAuthenticated){
         //如果未认证,重新回到登录页
         next({ name: 'Login' })
     }else{
         //如果已认证直接放行去to指向的目标资源
         next()
     }
 })

1.2 全局解析守卫(2.5.0 新增)

全局解析守卫是Vue在2.5.0之后新增的守卫类型,和全局前置守卫类似。但区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后解析守卫就被调用。

1.3 全局后置钩子

全局后置钩子函数和守卫不同,在守卫执行的过程中,挂载到守卫的执行周期中,不会影响守卫导航本身。

router.afterEach((to, from) => {
    //因为没有next函数所以全局后置钩子不会影响导航本身
})

1.4 路由独享守卫(私有守卫,非全局)

路由独享守卫就是将守卫设置到路由对象中,作为此路由的私有守卫。

const router = new VueRouter({
    routes: [
        {
            path: '/foo',
            component: Foo,
            beforeEnter: (to, from, next) => {
                // 使用方式和全局前置守卫相同
            }
        }
    ]
})

1.5 组件内守卫

组件内守卫,就是在组件内部定义的守卫。

const Foo = {
    template: `...`,
    beforeRouteEnter(to, from, next) {
        // 在渲染该组件的对应路由被 confirm 前调用
        // 不!能!获取组件实例 `this`
        // 因为当守卫执行前,组件实例还没被创建
    },
    beforeRouteUpdate(to, from, next) {
        // 在当前路由改变,但是该组件被复用时调用
        // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
        // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
        // 可以访问组件实例 `this`
    },
    beforeRouteLeave(to, from, next) {
        // 导航离开该组件的对应路由时调用
        // 可以访问组件实例 `this`
    }
}

2.守卫的完整运行流程

接下来我们来看看守卫的完整运行流程:

1.导航被触发;

2.在失活的组件里调用 beforeRouteLeave 守卫;

3.调用全局的 beforeEach 守卫;

4.在重用的组件里调用 beforeRouteUpdate 守卫;

5.在路由配置里调用 beforeEnter;

6.解析异步路由组件;

7.在被激活的组件里调用 beforeRouteEnter;

8.调用全局的 beforeResolve 守卫;

9.导航被确认;

10.调用全局的 afterEach 钩子;

11.触发 DOM 更新;

12.调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

全局前置守卫详解

全局前置守卫是在工作中用的最多的守卫,一般用于进行资源的保护(权限认证和授权认证),下面我们来看看壹哥具体的案例,代码如下:

<!DOCTYPE html>
<html>
        <head>
                <meta charset="utf-8" />
                <title>路由守卫</title>
        </head>
        <body>
                <div id="app">
                        <h4>路由守卫案例</h4>
                        <p>    
                                
                                <router-link to="/foo">Go to Foo</router-link>
                                <router-link to="/bar">Go to Bar</router-link>
                        </p>
                        <div>
                                
                                <router-view></router-view>
                        </div>
                </div>
                
                <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
                <script src="https://unpkg.com/[email protected]/dist/vue-router.js"></script>
                
                <script>
                        //定义组件
                        const Foo = { template: '<div>页面1(不需要权限)</div>' }
                        const Bar = { template: '<div>页面2(需要认证)</div>' }
                        const Login = { template: '<div>登录页</div>' }
                        //定义路由映射
                        const routes = [
                          { path: '/foo',name:'Foo', component: Foo },
                          { path: '/bar',name:'Bar', component: Bar },
                          { path: '/Login',name:'Login', component: Login }
                        ]
                        //创建路由
                        const router = new VueRouter({
                          routes // (缩写) 相当于 routes: routes
                        })
                        
                        //路由守卫(全局前置路由守卫)
                        router.beforeEach((to, from, next) => {
                                if(to.name==='Bar'){
                                        //跳转认证页面
                                        next({name:'Login'})
                                }else if(to.name==='Foo'){
                                        //直接放行
                                        next();
                                }else{
                                        next();
                                }
                        })
                        
                        var app = new Vue({
                          el: '#app',
                          data: {
                            
                          },
                          /* 注册路由 */
                          router:router
                        })
                </script>
        </body>
</html>

以上就是Vue中路由守卫的一些小秘密,你get到了吗?大家不妨把最后的案例运行一下,仔细体会一下Vue路由的具体作用。

猜你喜欢

转载自blog.csdn.net/GUDUzhongliang/article/details/132359759