您现在的位置是:首页 >其他 >vue中独特的路由守卫网站首页其他

vue中独特的路由守卫

前进的探索者 2023-06-22 04:00:02
简介vue中独特的路由守卫

1.对路由守卫的认识
路由导航守卫:导航守卫就是在路由跳转前后的一些钩子函数

路由守卫分为三种:全局导航守卫,路由守卫,组件内导航守卫。路由跳转本身是一个比较复杂的过程,但是可以通过导航守卫把这个过程进行细化,可以在每个细化的过程(钩子函数)中进行相应的操作。

路由拦截:在路由跳转到指定的路有前,可以手动让其跳转到其他的路由界面,并且也可以让跳转停止掉。

2.路由守卫的分类
1 全局守卫:

全局前置守卫:beforeEach 会多次触发,

全局解析守卫:beforeResolve 解析守卫

全局后置守卫:afterEach 把组件实例对象传入到组件beforeRouteEnter守卫的next回调中

2.路由守卫:

beforeEnter  路由内的独享守卫

3.组件内的守卫:

beforeRouteEnter 进入组件之前触发,只在进入组件时触发一次

beforeRouterUpdate 组件更新之前触发(动态参数变化查询字符串变化)进入组件后参数变化可多次触发

beforeRouterLeave 离开路由组件之前触发 只在离开组件时触发一次

3.关于导航触发的全过程
1.先在失活的组件里面执行组件离开的守卫(beforeRouterLeave)

2.调用全局前置守卫(beforeEach)

3.在重复使用组件执行beforeRouteUpdate

4.在去执行路由独享守卫beforeEnter

5.在激活的组件里面执行beforeRouteEnter守卫

6.执行全局的解析守卫 beforeResolve

7.执行全局的后置守卫 afterEach

8.再去执行beforeRouteEnter里面的回调函数next(组件实例对象)

4.路由守卫的详细介绍
1.全局导航前置守卫

// 全局导航守卫在router/index.js 下面添加
//全局的前置守卫:可以进行登陆界面是否要显示,判断是否需要进行登录判断
router.beforeEach((to,from,next)=>{
  // to:目标路由的配置对象(到哪去)
  // from:是跳转前的路由对象(从哪来)
  // next//把当前跳转操作交给下一个路由守卫,如果不添加next,这个时候跳转就会停止掉
  console.log("1 beforeEach,只要路由发生变化都会触发的钩子函数,或者每一次路由进入也会触发");
  // to.matched 找到目标路由下所有的不管是一级路由还是二级路由
  // record.meta.requireLogin 找到一个路由匹配对象的 requireLogin:true
  var token = localStorage.getItem("ll")//获取登录成功的token
  if (to.matched.some(record=>{return record.meta.requireLogin})) {
    // 条件成立说明需要进行登陆判断
    if (token) {
      // 存在token则跳转继续,显示目标路由
      next()
    }else{
      // 没登陆直接进入登陆界面
      next("/login")
    }
  }else{ //else说明不需要登录判断,直接跳转目标路由
    next()//把当前跳转操作交给下一个路由守卫,如果不添加next(),这个时候跳转就会停止掉.next(false)会停止路由的跳转
  }
})

2.全局的解析守卫位置和全局前置导航的位置相同

router.beforeResolve((to,from,next)=>{
  console.log(to,from,2);
  next()
})

3.全局的后置守卫位置和全局前置导航的位置相同

全局后置守卫执行结束会执行组件前置守卫中的next函数

router.afterEach((to,from,next)=>{
  console.log(to,from,3);
})

4.路由独享守卫

const routes = [
  {
    path: '/demo/:id',
    name: 'Demo',
    component: () => { //只走一次,留下缓存,后面使用缓存
      console.log("解析组件demo的过程");
      return import('../views/Demo.vue')},
    meta:{requireLogin:true},//添加一个元数据,自定义属性,可以在守卫函数通过to或者from取到元数据,然后可以通过requireLogin进行判断该路由是否需要进行登陆判断
    // 第二种类型:路由独享守卫
    beforeEnter: (to, from, next) => {
      console.log('在进入到一个路由之前,专门用来守卫当前路由的。如果是同一个路由下的两个子路由在进行跳转的时候不会触发,必须重新进入才会触发');
      next()
    }
  },
]

5.组件内的守卫

// 第三种导航守卫,写在一个组件的内部,组件内的守卫
    beforeRouteEnter: (to, from, next) => {
        // console.log(this);//undefined 组件实例不存在,没有this
        console.log("进入到当前路由组件之前调用");
        next(vm=>{
            //vm创建好的组件实例,即this对象
            vm.http.get("/books.json").then(res=>{
                vm.books = res.data.data
                console.log(vm.books,"在全局后置守卫执行之后把组件实例传入到组件守卫的beforeRouteEnter的next函数里面");
            })
        })
    },
    beforeRouteUpdate (to, from, next) {
        console.log("当前路由组件更新的时候调用,当动态路由参数发生变化的时候触发,例如/demo/1和/demo/2,当查询字符串发生变化的时候也会触发");
        this.b = this.books.filter((b,j)=>{
            return b.id == to.params.id
        })
        next()
    },
    beforeRouteLeave (to, from, next) {
        console.log("当离开当前路由组件之前调用,一般是在离开之前是否还有其它操作没有");
        var answer = window.confirm("Do you want leave this page,has some unsave changes?") 
        if (answer) {
            next()
        }else{
            next(false)//停止导航切换.0.0
        }   
    }

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。