vue路由-3-监听-守卫-解决created只走一次的问题

简介: 1.路由确实在vue大型项目中听常用的,挺重要的,但是一般的小项目其实不用也没事2.大家觉得难的 可能重点是路由守卫3.那就试试自己能不能讲明白吧4.当然还是建议大家看看 官网的路由守卫

1. 前言


1.路由确实在vue大型项目中听常用的,挺重要的,但是一般的小项目其实不用也没事

2.大家觉得难的 可能重点是路由守卫

3.那就试试自己能不能讲明白吧

4.当然还是建议大家看看 官网的路由守卫


2. 先从路由监听说起吧


2.1 首先路由系列的文章vue路由-2编程式导航存在通过路由切换的时候,created直走一次的问题,

2.2 解决方案 监听 -1

参数的名字 一般都叫tofrom或者 newV, oldV

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

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


watch:{
                   $route(to,from){
                    console.log(from.path);//从哪来
                    console.log(to.path);//到哪去
            //界面变化了就发请求
               }
            },

这种写法也有个问题,第一次的时候不走

2.3 解决方案 监听-2

immediate:true 设置 立刻监听,第一次切换也会走的


watch:{
            $route:{
                immediate:true,
                 handler(newValue,oldValue){
                        console.log("详情页---newV:",newValue);
                         console.log("详情页---oldV:",oldValue);
                      }
               },
        },



3.导航守卫


3.1 官方定义

正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。

3.2 场景

路由守卫嘛 就是保护路由的 ,怎么保护呢

主要就是在进入路由之前进行拦截

一般都是 某些界面必须登录才能访问的时候做个守卫,比如

最近某些购物类网站,点击购物车相关操作话,如果你没有登录的话,会直接跳转到登录界面;

在以前是会正常跳到购物车界面,付账的时候在登录,登录后购物车信息是都在的


5. 全局守卫配置


5.1 标记需要进行守卫的路由

一般通过路由配置meta属性

路由文件


{
    path: '/address',
    name: 'Address',
    component: () => import('../views/address.vue'),
    meta:{
       title: "标题",
       icon: "图标",
       needLogin:true
    }
  },

1.meta哈哈没想到这个时候正式元宇宙大火的概念

2.扯回整体, 这里的meta是一些原配置信息

3.needLogin 用来标记某个页面路由是否需要登录才能访问

4.title实际开发中,如果配置菜单 也可以配置标题

5.icon实际开发中,如果配置菜单 也可以配置菜单图标

5.2守卫逻辑

  1. 判断哪个路由需要守卫if(to.meta.needLogin)
  2. 不需要守卫的 直接 走else next()
  3. 需要守卫的进行第二步判断, 当前是否登录
    登录的时候发请求 请求成功 存放 一个auth或者token到本地localStorage
  4. 如果现在已经登录 直接 next()放行
    5.如果没登录 嘿嘿 此路是我开,此树是我栽,要想过,得听话,
    回去登录去

注意的是 这里跳转到登录界面,需要把拦截路由的地址传过去,

为啥传???

那还不是为了用户体验,为了顾客,为了逻辑闭环

比如用户从点击购物车界面 跳转到了登录界面,用户登录后,肯定要给界面重置到 购物车界面嘛,

5.3 具体守卫代码 方式-1


// 全局守卫
router.beforeEach((to,from,next)=>{
  // 判断路由是否需要守卫
  //meta数据的方式
  if(to.meta.needLogin){
    // 是否登录
    if(localStorage.token){
      next()
    }else{
      next("/login?redirect="+to.fullPath)
    }
  }else{
    //不需要守卫,直接放行
    next()
  }
})
export default router


5.4具体守卫代码 方式-2


router.beforeEach((to, from) => {
  if (to.meta.needLogin) {//说明当前路由需要登录之后才可进入
    if (!localStorage.token) {//还没登录 不为空 就行 简单的判断
      // return "/login?redirect=" + to.name; 
      return "/login?redirect=" + to.fullPath;
    }
  }
})

这个不用 next,但如果参数写了next 就必须用,不然不放行嘛,界面就一个也出不来

to.name 的方式 传的是 命名路由 跳转的时候也需要使用命名路由跳转


this.$router.push({ name: this.$route.query.redirect});


to.fullPath 的方式 传的是 path路径

push也行,但是也可用 replace


this.$router.replace(this.$route.query.to);



6. 登录后跳回去的配置



loginBtn() {
      this.isdisabled = true;
      setTimeout(() => {
        alert("登录成功");
        this.isdisabled = false;
        localStorage.token = "yzs假冒token";
        // 登录成功之后 回到被拦截的页面
       this.$router.replace(this.$route.query.redirect);
        }
      }, 3000);
    },

])5%CGFCTE`A6I%E62$4X5P.png

守卫的时候传参方式

1.可以传 通过query传递 path路径

2.也可以通过 params 传参

3.注意登录成功后 获取值的方式就行


query:{redirect:"/two"} ,
        params: { toRouterName: to.name }})

命名路由的写法


this.$router.push({ name: this.$route.params.toRouterName });


这样就形成了逻辑闭环 ,当然你还需退出或者注销的时候修改状态


7.单个路由守卫


全局守卫,肯定是每个路由跳转都要进行判断的,也就是each遍历,这里面的效率问题就需要考虑

所以,如果只是极个别的路由需要判断,那就单独守卫

比如保护整村的人,和保护一个人那是完全不一样的

注意和全局的不同

  1. 钩子不一样了,这个是Enter进到这个路由了,判断
    2.因为已经进到这个路由了,自然也不需要在判断哪个路由需要守卫了
  2. 直接判断登录状态就行


{
    path: '/cart',
    name: 'Cart',
    component: () => import("@/views/cart.vue"),
    meta: {
      title: "标题",
      icon: "图标",
      needLogin: true
    },
    //************* */ 单个的路由守卫
    beforeEnter(to, from, next) {
      //  判断当前是否登录
      if (localStorage.token) {
        next()
      } else {
        next({ name: "Three",
        query:{to:"/cart"} ,
        params: { toRouterName: to.name },})
      }
    }
  },



8. 组件级守卫


1.和 methds 是同级的

2.beforeRouteEnter 和 单独的守卫beforeEnter写法是不一样的

3.这个是存储 localStorage的逻辑

4.login页和单个守卫用的是一样的


beforeRouteEnter(to, from, next) {
    // 当前是否登录
    if (localStorage.token) {
      next();
    } else {
      next({ name: "Login", params: { toRouterName: to.name } });
    }
  },



9. 组件级守卫 钩子详解



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`
  }
}

1. 注意 Enter钩子不能访问 this

因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。

不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。


beforeRouteEnter (to, from, next) {
  next(vm => {
    // 通过 `vm` 访问组件实例
  })
}

注意

beforeRouteEnter 是支持给next传递回调的唯一守卫。对于 beforeRouteUpdatebeforeRouteLeave来说,this已经可用了,所以不支持传递回调,因为没有必要了。


10.完整的导航解析流程


1.导航被触发。

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

3.调用全局的beforeEach守卫。

4.在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。

5.在路由配置里调用 beforeEnter

6.解析异步路由组件。

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

8.调用全局的 beforeResolve守卫 (2.5+)。

9.导航被确认。

10.调用全局的afterEach 钩子。

11.触发 DOM 更新。

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


11. 想学习更多的实战配置 可以去看下各大开源的项目源码


比如各大框架的admin模板




相关文章
|
2天前
|
JavaScript
理解 Vue 的 setup 应用程序钩子
【10月更文挑战第3天】`setup` 函数是 Vue 3 中的新组件选项,在组件创建前调用,作为初始化逻辑的入口。它接收 `props` 和 `context` 两个参数,内部定义的变量和函数需通过 `return` 暴露给模板。`props` 包含父组件传入的属性,`context` 包含组件上下文信息。`setup` 可替代 `beforeCreate` 和 `created` 钩子,并提供类似 `data`、`computed` 和 `methods` 的功能,支持逻辑复用和 TypeScript 类型定义。
20 11
|
4天前
|
JavaScript
vue尚品汇商城项目-day07【vue插件-50.(了解)表单校验插件】
vue尚品汇商城项目-day07【vue插件-50.(了解)表单校验插件】
14 4
|
4天前
|
JavaScript
vue尚品汇商城项目-day07【51.路由懒加载】
vue尚品汇商城项目-day07【51.路由懒加载】
15 4
|
7天前
|
JavaScript
vue组件中的插槽
本文介绍了Vue中组件的插槽使用,包括单个插槽和多个具名插槽的定义及在父组件中的使用方法,展示了如何通过插槽将父组件的内容插入到子组件的指定位置。
|
5天前
|
JavaScript
vue消息订阅与发布
vue消息订阅与发布
|
6天前
|
JavaScript 前端开发 IDE
Vue学习笔记5:用Vue的事件监听 实现数据更新的实时视图显示
Vue学习笔记5:用Vue的事件监听 实现数据更新的实时视图显示
|
6天前
|
JavaScript 前端开发 API
Vue学习笔记4:用reactive() 实现数据更新的实时视图显示
Vue学习笔记4:用reactive() 实现数据更新的实时视图显示
|
6天前
|
JavaScript 前端开发
Vue学习笔记8:解决Vue学习笔记7中用v-for指令渲染列表遇到两个问题
Vue学习笔记8:解决Vue学习笔记7中用v-for指令渲染列表遇到两个问题
|
4天前
|
JavaScript
vue尚品汇商城项目-day07【vue插件-54.(了解)生成二维码插件】
vue尚品汇商城项目-day07【vue插件-54.(了解)生成二维码插件】
14 2
|
6天前
|
JavaScript 前端开发 API
Vue学习笔记7:使用v-for指令渲染列表
Vue学习笔记7:使用v-for指令渲染列表
下一篇
无影云桌面