vue中的三种导航守卫,元数据meta的应用

本文详细介绍了Vue中的三种导航守卫:全局、路由独享和组件独享,以及它们的使用场景。同时,文章探讨了路由元数据`meta`的应用,包括动态改变页面标题、权限验证和动态调整导航图标。通过示例代码,展示了如何通过后置导航守卫结合meta实现页面标题的动态更新,并讲解了如何利用meta进行权限管理和导航图标的变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

请添加图片描述

导航守卫

vue-router提供的导航守卫,守护每一次跳转
其本质是函数,当导航发生变化时自动执行
导航守卫分为三个级别

  • 全局导航守卫
  • 单个路由独享的导航守卫
  • 组件级别的导航守卫
全局导航守卫

可以使用router.beforeEach注册一个导航守卫,进入路由之前触发,当用户满足条件时,才可以进入导航,否则取消跳转。

我用到的一个导航守卫的案例是:当用户每次发送请求时都要从本地获取token然后,后端会判断token是否存在并判断token是否过期,这样本身就是一件非常麻烦的事情每次都要携带token带着数据向后端请求,所以我当时就在路由配置里定义了一个导航守卫,当每次发送请求先将请求拦截下来对其给其经过一个加工[也就是让每次的请求都携带上token再向后台发送]

接收三个参数

  • to:要进入的目标路由对象
  • from:从哪个路出发到达目标路由
  • next:一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
  1. next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
  2. next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
  3. next(‘/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
  4. next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
    案例演示
router.beforeEach((to,from,next)=>{
  console.log('to输出对象',to);
  console.log('from输出对象',from);
  next()// next()方法是起一个放行作用,不加next()这个请求是发送不出去的
})

在这里插入图片描述

一个案例

router.beforeEach((to,from,next)=>{
  if(to.name==='login'){
    return next() //当路由验证到login的时候不需要判断有没有login,因为首次登录肯定没有login
  }
  const token=localStorage.getItem('token')
  if(!token){
    return next('/login')// 当没有login时直接让路由跳转到登录路由下
  }
  
  next()// 上面token规则验证有后对请求放行
})

当没有token时是这样的

请添加图片描述
当有toke时请添加图片描述

导航守卫其实不只有前置导航守卫其实还有后置导航守卫
这些钩子函数不接受next()函数,也不会改变导航本身,用的相对较少
分享一个小案例来带过一下这个后置守卫
当vue写一本小说时用到上一章下一章时,页面可视区域最终会出现在页面底部用户每次切换章节都要把页面从上面拉下来这样的使用户体验堪称极差

请添加图片描述
那么用什么方法来保证每次页面进行路由跳转时可视区域都在顶部呢这里用到了路由后置守卫

router.afterEach((to, from) => {
  window.scrollTo(0, 0)
})
路由独享的导航守卫

只有跳到当前的这个路由下才会执行导航守卫
这种导航守卫定义在路由规则下

 {        
        path: '/',        
        name: 'login',        
        component: login,        
        beforeEnter: (to, from, next) => {          
            console.log('即将进入登录页面')          
            next()        
        }    
    }
组件独享导航守卫

可以在路由组件内直接定义以下路由导航守卫:

  • beforeRouteEnter
  • beforeRouteUpdate (2.2 新增)
  • beforeRouteLeav
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`
  }
}

需要注意,beforeRouteEnter组件内还访问不到this,因为该守卫执行前组件实例还没有被创建,需要传一个回调给 next来访问,例如:

beforeRouteEnter(to, from, next) {      
    next(target => {        
        if (from.path == '/classProcess') {          
            target.isFromProcess = true        
        }      
    })    
}

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

这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。注意 beforeRouteEnter 是支持给 next 传递回调的唯一守卫。对于 beforeRouteUpdate 和 beforeRouteLeave 来说,this 已经可用了,所以不支持传递回调,因为没有必要了

这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。

beforeRouteLeave (to, from, next) {
  const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
  if (answer) {
    next()
  } else {
    next(false)
  }
}
完整导航流程解读
  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 的回调函数,创建好的组件实例会作为回调函数的参数传入
路由元数据

在定义路由的时候后面可以跟一个meta字段。元数据可以作为自定义显示路由的标题

{
        path: '/a',
        name: 'a',
        component: A,
        meta:{title:'下章标题'}
      }

可以在组件内获取

{{$route.meta.title}

效果展示请添加图片描述
请添加图片描述
javascript这么获取请添加图片描述
请添加图片描述
路由导航中也可以拿到这个meta中的信息
请添加图片描述

元数据meta应用一通过路由的后置导航守卫+meta实现动态改变页面tag表标题

请添加图片描述
请添加图片描述
路由规则中如下定义

{
    path: '/book',
    name: 'book',
    component: Book,
    meta: {
      title: '《机器学习》'
    },
router.afterEach((to, from) => {
  window.scrollTo(0, 0)
  document.title = to.meta.title
})
元数据应用二在元数据内定义一个键用于权限验证

路由规则中的meta中定义随便一个用于定义当前用户权限的键,我这里定义的时requireAuth,这里用户需要权限的是true

{
    path: '/users/:id(\\d+)',
    name: 'userinfo',
    component: UsersInfo,
    meta: {
      title: '用户详情页',
      requireAuth:true,
    }
  },

在路由的前置导航中我定义的权限验证规则

router.beforeEach((to, from, next) => {
  if(!to.meta.requireAuth){
    return next()
  }else{
    return alert('您当前权限不足')
  }
  const token = localStorage.getItem('token')
  if (!token) {
    return next('/login') // 当没有login时直接让路由跳转到登录路由下
  }
  
}
  next()
})

请添加图片描述
但是这种权限的验证不推荐

元数据的应用三搭配路由后置导航实现动态改变导航的图标

在路由规则中定义meta,meta中定义要显示的图标
http://localhost:8080映射的是上级目录public,所以把meta中存放的ico文件放到public中,在定义icon的值时加上public映射的地址也就是http://localhost:8080
// meta定义内容展示如下

{
    path: '/login',
    name: 'login',
    component: Login,
    meta: {
      title: '登录',
      requireAuth: false,
      icon:'http://localhost:8080/login.ico'
    }

// 路由后置导航代码如下

router.afterEach((to, from) => {
  window.scrollTo(0, 0)
  document.title = to.meta.title
  document.querySelector('link[rel="icon"]').href=to.meta.icon //这里是获取dom中link标签并且rel属性值为icon的标签把它的href值改为元数据meta中定义的图标路径
})
<think>好的,用户想了解Vue.js导航守卫的使用方法和示例。我需要先回忆一下导航守卫的相关知识,并结合提供的引用内容来组织回答。 首先,导航守卫主要分为全局、路由独享和组件级三种类型。引用[1]提到了全局导航守卫,可以用来在路由跳转前后执行逻辑,比如权限检查或数据预加载。引用[4]中的命名路由示例可能和导航守卫的使用场景相关,比如在跳转时使用名称而不是路径。 接下来需要分点说明每种守卫的用法,并给出代码示例。全局守卫包括beforeEach、beforeResolve和afterEach,其中afterEach没有next参数。路由独享的beforeEnter可以在路由配置中定义。组件内的守卫包括beforeRouteEnter、beforeRouteUpdate和beforeRouteLeave,这些需要在组件选项中设置。 要注意引用中的例子,比如引用[1]的代码展示了在路由跳转前后执行逻辑,可以用来作为全局守卫的示例。权限检查是一个常见用例,比如在beforeEach中检查用户是否登录,如果未登录则重定向到登录页面。数据预加载可能在beforeRouteEnter中完成,但需要注意这个时候组件实例还没创建,所以需要通过回调访问实例。 另外,引用[4]提到命名路由的使用,可能在导航守卫中结合名称进行更灵活的跳转控制。需要确保示例代码符合Vue Router的语法,比如使用next()方法来控制导航流程。 还要考虑用户可能遇到的问题,比如守卫的执行顺序,next函数的正确使用,以及如何避免死循环。比如在beforeEach中如果没有调用next(),导航会一直挂起。此外,在beforeRouteEnter中访问组件实例需要通过回调,因为此时组件还未创建。 最后,生成的相关问题需要围绕导航守卫的深入应用,比如执行顺序、异步处理、权限控制等,帮助用户进一步学习。</think>### Vue.js 导航守卫使用方法与示例 导航守卫Vue Router提供的核心功能,用于在路由跳转前后添加控制逻辑,例如权限验证、数据预加载等[^1]。以下是具体使用方法及示例: --- #### 一、全局导航守卫 1. **前置守卫 `beforeEach`** 在路由跳转前触发,常用于权限校验: ```javascript const router = new VueRouter({ /*...*/ }); router.beforeEach((to, from, next) => { if (to.meta.requiresAuth && !isAuthenticated) { next('/login'); // 跳转登录页 } else { next(); // 继续导航 } }); ``` 2. **解析守卫 `beforeResolve`** 在所有组件内守卫和异步路由组件解析后触发: ```javascript router.beforeResolve((to, from, next) => { // 执行数据预加载等操作 next(); }); ``` 3. **后置钩子 `afterEach`** 在导航完成后触发(无`next`参数): ```javascript router.afterEach((to, from) => { logPageView(to.path); // 记录页面访问 }); ``` --- #### 二、路由独享守卫 直接在路由配置中定义`beforeEnter`: ```javascript const routes = [ { path: '/dashboard', component: Dashboard, beforeEnter: (to, from, next) => { if (!userHasPermission()) { next('/403'); // 无权限跳转 } else { next(); } } } ]; ``` --- #### 三、组件内守卫Vue组件中定义以下钩子: 1. **`beforeRouteEnter`** 组件实例未创建时触发,适合异步数据加载: ```javascript export default { beforeRouteEnter(to, from, next) { fetchData(to.params.id).then(data => { next(vm => vm.setData(data)); // 通过回调访问组件实例 }); } }; ``` 2. **`beforeRouteUpdate`** 当前路由改变但组件复用时触发(如动态参数变化): ```javascript beforeRouteUpdate(to, from, next) { this.fetchData(to.params.id); // 更新数据 next(); } ``` 3. **`beforeRouteLeave`** 离开当前路由前触发,常用于阻止未保存修改: ```javascript beforeRouteLeave(to, from, next) { if (this.formModified) { const confirm = window.confirm('数据未保存,确认离开?'); next(confirm); // 根据用户选择决定是否继续 } else { next(); } } ``` --- #### 四、典型应用场景 1. **权限控制** 结合路由元信息`meta`实现动态鉴权[^4]。 2. **页面追踪** 通过`afterEach`记录用户访问路径。 3. **数据预加载** 在`beforeRouteEnter`中提前获取渲染所需数据。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值