vue-router 导航守卫

官网API

文章目录

            • 全局导航守卫
            • 全局前置守卫
            • 全局解析守卫
            • 全局后置钩子
            • 路由独享守卫
            • 组件内的守卫

导航守卫的作用:vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。

项目中应用场景:路由页面跳转时候进行登陆验证;路由跳转判断;

有多种机会植入路由导航过程中:全局路由, 单个路由独享的, 或者组件级的。

全局守卫包括:router.beforeEach(全局前置守卫)、router.beforeResolve(全局解析守卫)、router.afterEach(全局后置钩子)

单个路由独享的导航守卫:在路由配置上直接定义 beforeEnter 守卫

组件内守卫包括:在组件内定义路由的导航守卫,有beforeRouteEnter 、beforeRouteUpdate 、beforeRouteLeave

每个导航守卫都接受3个参数 from 、to、next() ,参数的定义如下:

to: Route: 即将要进入的目标 路由对象

from: Route: 当前导航正要离开的路由

next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。

next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那 么 URL 地址会重置到 from 路由对应的地址。

next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。

next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

注意事项:

1、确保要调用 next 方法,否则钩子就不会被 resolved。

2、当一个导航触发时,导航守卫按照顺序调用。守卫是异步解析执行,导航在所有守卫 resolve 完之前一直处于 等待中。

全局导航守卫

源码: to:Route, to是route类型 route就是router/index.js 里面定义的一个个路由

所以在route里面加入元数据meta (描述数据的数据)
router/index.js

{
  path:'/home',
  component: Home ,
  meta:{
    title:'首页'
  }
}

...
//前置钩子 跳转之前回调
router.beforeEach((to,from,next) =>{
  //从from跳转到to
  document.title = to.matched[0].meta.title //to里面没有title,要去route里面加入
  //不写 matched[0] 第一个路由会显示为undefind
  console.log(to)
  next()//是必须要调用的
})

vue-router 导航守卫_第1张图片

全局前置守卫

router.beforeEach 在每次进入页面和页面刷新时都要经过该守卫判断
使用:

import Vue from 'vue'
import VueRouter from 'vue-router'
import Index from '../views/Index.vue'
import {routerList} from '../router/RouterList.js'
Vue.use(VueRouter)

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes:routerList
})

router.beforeEach((to,from,next)=>{
        if(to.path == '/page-1'){
            next({path:'/page-3'})
        }else{
            next()
        }     
})


export default router

参数值:to from next

to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子(如果没有调用页面进程会反复调用)
使用:next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新 的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。

全局解析守卫

router.beforeResolve和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用
使用:

import Vue from 'vue'
import VueRouter from 'vue-router'
import Index from '../views/Index.vue'
import {routerList} from '../router/RouterList.js'
Vue.use(VueRouter)

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes:routerList
})

router.beforeRouteLeave((to,from,next)=>{
        if(to.path == '/page-1'){
            next({path:'/page-3'})
        }else{
            next()
        }     
})


export default router
全局后置钩子

router.afterEach 页面进入之后执行 不会接受 next 函数也不会改变导航本身,不需要主动调用next()函数
使用:

import Vue from 'vue'
import VueRouter from 'vue-router'
import Index from '../views/Index.vue'
import {routerList} from '../router/RouterList.js'
Vue.use(VueRouter)

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes:routerList
})

router.afterEach((to,form)=>{
      console.log(to)  
})


export default router

参数:to from

to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由

路由独享守卫

beforeEnter你可以在路由配置上直接定义 beforeEnter 守卫
使用:

    {
        path: '/',
        redirect: '/page-1',
        name: 'index',
        component: () =>  import ('../views/Index.vue'),  
        children: [
             {
                path: '/page-1',
                name: 'Page-1',
                component: () =>import ('../views/page1/page-1.vue'),
                beforeEnter: (to, from, next) => {
                     console.log(to)
                     next()
                }                   
            },
            {
                path: '/page-2',
                name: 'Page-2',
                component: () =>
                    import ('../views/page2/page-2.vue')
            },
   ]

参数: to from next 这些守卫与全局前置守卫的方法参数是一样的(必须调用next())

组件内的守卫

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

<template>
  <div>page2div>
template>

<script>
// eslint-disable-next-line @typescript-eslint/no-this-alias

export default {
    data() {
        return {
            
        }
    },
  beforeRouteEnter(to, from, next) {
    // ...
    console.log(to);
    next();
  },
  beforeRouteLeave(to, from, next) {
    console.log(to);
    next();
  },
  // eslint-disable-next-line @typescript-eslint/no-empty-function
  beforeRouteUpdate(to, from, next) {
    console.log(to);
    next();
  }
};
script>

<style lang="less" scoped>
style>

你可能感兴趣的:(vue-router)