Vue中的路由守卫(路由跳转前中后的一些钩子函数)

  • 作用:对路由进行权限的控制

Vue中的路由守卫分为三种

  1. 全局路由守卫(前置和后置)
  2. 独享路由守卫
  3. 3.组件内路由守卫

(1)-全局路由守卫(所有路由组件都会经过)

  • 1.全局前置路由守卫(在index.js中暴露路由组件之前编写)

    • 初始化以及每次路由跳转之前调用这个给api里面的函数
      //前置全局路由守卫
      router.beforeEach((to,from,next)=>{})
  • 回调函数中的参数,to:进入到哪个路由去,from:从哪个路由离开,next():放行函数,决定是否展示你要看到的路由页面。

  • 从名字全局前置守卫不难理解,它是全局的,即对 整个单页面应用(SPA) 中的所有路由都生效,所以当定义了全局的前置守卫,在进入每一个路由之前都会调用这个回调,那么如果你在回调中对路由的跳转条件判断出错,简单点就是死循环…因为你遗漏了某种路由跳转的情况,守卫会一直执行。所以在使用全局前置守卫的时候一定要判断清楚可能会出现的路由跳转的情况。在的项目当中常用于进行权限的判断,相当于门卫查看你进门的证件

  • 2.全局后置路由守卫(在index.js中暴露路由组件之前编写)

    • 初始化以及每次路由跳转之后调用这个给api里面的函数
      //全局后置路由守卫
      router.afterEach((to, from) => {})
  • 回调函数中只有两个参数,to:进入到哪个路由去,from:从哪个路由离。

  • 理解了全局前置守卫,那么全局后置守卫也就那么一回事。全局后置守卫是整个单页应用中每一次路由跳转后都会执行其中的回调。所以多用于路由跳转后的相应页面操作,并不像全局前置守卫那样会在回调中进行页面的重定向或跳转。项目当中常用于进行路由跳转网页标题的自定义

案例代码展示:

  • 要求:通过设置全局路由守卫(前置和后置)控制访问home组件下的newsmessage组件需要权限{localhost下需要有school:wyu}[前置路由守卫],并且路由的跳转,页面的标题也随之改变(通过meta属性设置参数实现)[后置路由守卫]
  • router-index.js
    // 这里配置路由(创建整个应用页面的路由器)

    // 首先引入路由
    import VueRouter from "vue-router";

    // 引入各个组件
    import About from '../pages/About'
    import Home from '../pages/Home'
    import Message from '../pages/Message'
    import News from '../pages/News'
    import Detail from '../pages/Detail'

    // 创建路由器
    const router = new VueRouter({
    // 一级路由
    routes:[
    {
    //设置管理路由:About
    name: 'guanyu',
    path:'/about',
    component: About,
    meta:{title:'关于'},
    },
    {
    //设置管理路由:Home
    name: 'shouye',
    path:'/home',
    component: Home,
    meta:{title:'主页'},

    // 二级路由(children属性)
    children:[//通过children配置子级路由
    {
    // 使用二级路由过后的path不需要再加上"/"
    name: 'xiaoxi',
    path:'message',
    component: Message,
    // 设置路由的元信息(程序员自定义的一些信息)
    meta:{
    // 设置鉴权标志,to带有这个标志的一律鉴定权限
    isAuth:true,
    title:'消息',
    },

    // 使用三级路由
    children:[
    {
    // 给这个三级路由命名未"xiangqing"
    name : 'xiangqing',
    path:'detail',
    component: Detail,

    props(route){//这里传入route($route也可以)就能获取到本地路由上的所有数据
    return {
    // 在通过对象赋值的方式传递数到指定的组件(route组件)即可
    id: route.query.id,
    title: route.query.title
    }
    },

    meta:{
    // 设置鉴权标志,to带有这个标志的一律鉴定权限
    isAuth:true,
    title:'详情',
    },
    }
    ]
    },
    {
    // 使用二级路由过后的path不需要再加上"/"
    name:'xinwen',
    path:'news',
    component: News,
    meta:{
    // 设置鉴权标志,to带有这个标志的一律鉴定权限
    isAuth:true,
    title:'新闻',
    },
    }
    ]
    },

    ]
    })

    // 设置全局路由守卫(在暴露路由之前)
    // 1.全局前置路由守卫
    // 使用路由全新的api: beforeEach(函数)
    // 表示:初始化以及每次路由跳转之前调用这个给api里面的函数
    router.beforeEach((to,from,next)=>{
    // 里面接收三个参数:to(跳向哪个路由组件) from(来自哪个路由组件) next(放行)
    console.log('前置路由守卫的三个参数:',to , from, next);

    // 设置访问权限(localhost里面存数据为school:wyu为放行可见message组件和news组件)
    if(to.meta.isAuth){//检查meta信息判断是否需要鉴定权限
    if(localStorage.getItem('school') === 'wyu'){
    next()//调用放行属性,允许访问该路由组件
    }
    else{
    alert('学校名不对,无权限查看!')
    }
    }
    else{
    next()//不需要鉴权则直接放行
    }
    })


    //2.全局后置路由守卫
    // 使用路由全新的api: afterEach(函数)
    // 表示:初始化的时候被调用、每次路由切换之后被调用
    // 项目当中一般是用于转换页面标题为自定义的title
    router.afterEach((to,from)=>{
    // 里面接收两个参数:to(跳向哪个路由组件) from(来自哪个路由组件)
    // console.log('后置路由守卫',to,from)
    //每次跳转展示对应的路由组件标题(meta里面的title属性)
    document.title = to.meta.title || 'wyu'
    })

    // 向外暴露路由器
    export default router

结果展示:

image

(2)-独享路由守卫(指定路由组件独有的并且只有前置没有后置)

  • 1.独享路由守卫(在index.js中对应的路由组件规则里编写)
    //独享路由守卫
    beforeEnter:(to,from,next)=>{}
  • 与全局路由守卫用法一致,但是只能针对一个页面使用,但是没有独享后置路由守卫

案例代码展示:

  • 要求:通过设置独享路由守卫控制访问访问home组件下的news组件需要权限{localhost下需要有school:wyu},并且路由的跳转,页面的标题也随之改变(通过meta属性设置参数实现)[后置路由守卫]
  • router-index.js
    // 这里配置路由(创建整个应用页面的路由器)

    // 首先引入路由
    import VueRouter from "vue-router";

    // 引入各个组件
    import About from '../pages/About'
    import Home from '../pages/Home'
    import Message from '../pages/Message'
    import News from '../pages/News'
    import Detail from '../pages/Detail'

    // 创建路由器
    const router = new VueRouter({
    // 一级路由
    routes:[
    {
    //设置管理路由:About
    name: 'guanyu',
    path:'/about',
    component: About,
    meta:{title:'关于'},
    },
    {
    //设置管理路由:Home
    name: 'shouye',
    path:'/home',
    component: Home,
    meta:{title:'主页'},

    // 二级路由(children属性)
    children:[//通过children配置子级路由
    {
    // 使用二级路由过后的path不需要再加上"/"
    name: 'xiaoxi',
    path:'message',
    component: Message,
    // 设置路由的元信息(程序员自定义的一些信息)
    meta:{
    // 设置鉴权标志,to带有这个标志的一律鉴定权限
    isAuth:true,
    title:'消息',
    },

    // 使用三级路由
    children:[
    {
    // 给这个三级路由命名未"xiangqing"
    name : 'xiangqing',
    path:'detail',
    component: Detail,

    props(route){//这里传入route($route也可以)就能获取到本地路由上的所有数据
    return {
    // 在通过对象赋值的方式传递数到指定的组件(route组件)即可
    id: route.query.id,
    title: route.query.title
    }
    },

    meta:{
    // 设置鉴权标志,to带有这个标志的一律鉴定权限
    isAuth:true,
    title:'详情',
    },
    }
    ]
    },
    {
    // 使用二级路由过后的path不需要再加上"/"
    name:'xinwen',
    path:'news',
    component: News,
    meta:{
    // 设置鉴权标志,to带有这个标志的一律鉴定权限
    isAuth:true,
    title:'新闻',
    },

    // 设置独享路由守卫
    beforeEnter: (to, from, next) => {
    // 设置访问权限(localhost里面存数据为school:wyu为放行可见message组件和news组件)
    if(to.meta.isAuth){//检查meta信息判断是否需要鉴定权限
    if(localStorage.getItem('school') === 'wyu'){
    next()//调用放行属性,允许访问该路由组件
    }
    else{
    alert('学校名不对,无权限查看!')
    }
    }
    else{
    next()//不需要鉴权则直接放行
    }
    }
    }
    ]
    },

    ]
    })

    //设置全局后置路由守卫-初始化的时候被调用、每次路由切换之后被调用
    router.afterEach((to,from)=>{
    console.log('后置路由守卫',to,from)
    // 路由跳转后将meta下的title属性同步到网页标题上
    document.title = to.meta.title || 'wyu'
    })

    // 向外暴露路由器
    export default router

结果展示:

image

(3)-组件路由守卫(在对应的组件(组件.vue)当中编写)

  • 1.通过路由规则(index.js中定义)进入该组件
    //进入组件api
    beforeRouteEnter:(to,from,next)=>{}
  • 2.通过路由规则(index.js中定义)离开该组件
    //离开组件api
    beforeRouteLeave:(to,from,next)=>{}
  • 上面三个参数(to,from,next)的使用基本一致

案例代码展示:

  • 要求:通过设置组件路由守卫控制访问访问about组件需要权限{localhost下需要有school:wyu},并且路由的跳转,页面的标题也随之改变(通过meta属性设置参数实现)[后置路由守卫]
  • About组件
    <template>
    <h2>我是About的内容</h2>
    </template>

    <script>
    export default {
    name : 'About' ,

    // 设置组件路由守卫
    //1.进入组件路由守卫:通过路由规则(不能通过a标签或者是组件标签表用),进入该组件时被调用
    beforeRouteEnter (to, from, next) {
    console.log('你通过路由规则进入了App组件');
    // 设置访问权限(localhost里面存数据为school:wyu为放行可见message组件和news组件)
    if(to.meta.isAuth){//检查meta信息判断是否需要鉴定权限
    if(localStorage.getItem('school') === 'wyu'){
    next()//调用放行属性,允许访问该路由组件
    }
    else{
    alert('学校名不对,无权限查看!')
    }
    }
    else{
    next()//不需要鉴权则直接放行
    }
    },

    //2.离开组件路由守卫:通过路由规则(不能通过a标签或者是组件标签表用),离开该组件时被调用
    beforeRouteLeave (to, from, next) {
    // 可以设置一些离开组件时的逻辑
    console.log('你通过路由规则离开了About组件');
    // 但是一定要记得调用next(),不然就不能离开该组件了
    next()
    }

    }
    </script>

结果展示:

image

三个参数(to,from,next)的展示

image