前端vue入门(纯代码)35_导航守卫

这篇具有很好参考价值的文章主要介绍了前端vue入门(纯代码)35_导航守卫。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

星光不问赶路人,时光不负有心人

【33.Vue Router--导航守卫】

导航守卫

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

记住参数或查询的改变并不会触发进入/离开的导航守卫。你可以通过观察 $route 对象来应对这些变化,或使用 beforeRouteUpdate 的组件内守卫。

全局前置守卫

你可以使用 router.beforeEach 注册一个全局前置守卫:

const router = new VueRouter({ ... })

//全局前置守卫
router.beforeEach((to,from,next) =>{
  //第一个参数to,包含的内容是切换后的路由对象,也就是跳转后的路由对象
  //第二个参数from,包含的内容的是切换前的路由对象,也就是跳转前的路由对象
  //第三个参数next(),是否往下执行,执行的话,如果不写的话路由就不会跳转,操作将会终止
    console.log('前置路由守卫',to,from,next)  
})

前端vue入门(纯代码)35_导航守卫,Vue前端,vue.js,前端,javascript

当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve【解析】 完之前一直处于 等待中

① 执行时间
初始化时执行,每次路由切换前执行
② 使用场景
全局前置守卫通常用来进行路由跳转的一些信息判断,判断是否登录,是否拿到对应的路由权限等等。

每个守卫方法接收三个参数:

  • to: Route: 即将要进入的目标路由对象
  • from: Route: 当前导航正要离开的路由
  • next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。【进行下一个路由】
    • next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
    • next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
    • next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: truename: 'home' 之类的选项以及任何用在 router-linkto prop或 router.push 中的选项。
    • next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

确保 next 函数在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错。这里有一个在用户未能验证身份时重定向到 /login 的示例:

// BAD  错误示范
router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
  // 如果用户未能验证身份,则 `next` 会被调用两次
  next()
})
// GOOD  推荐写法
router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
  else next()
})

route/index.js

// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router';
//引入组件
import About from '../pages/About';
import Home from '../pages/Home';
import Cartoon from '../pages/Cartoon';
import Stars from '../pages/Stars';
import Detail from '../pages/Detail';

//创建并暴露一个路由器
const router = new VueRouter({
  // 定义一些路由
  // 每个路由都需要映射到一个组件。
  routes: [
	//配置路由路径和路由组件
	{
	  name: 'firstabout',
	  path: '/about',
	  component: About, //要跳转到的组件
      meta:{title:'关于'}
	},
	{
	  //一级路由配置
      name: 'firsthome',
	  path: '/home',
	  component: Home,
      meta:{title:'主页'},
	  children: [
		{
		  //二级路由配置
		  name: 'Hcartoon',
		  path: 'cartoon',
		  component: Cartoon,
          meta:{isAuth: true,title:'卡通'},
		},
		{
		  //二级路由配置
          name:'secondstars',
		  path: 'stars',
		  component: Stars,
          meta:{isAuth: true,title:'明星'},
		  children: [
			{
              //三级路由配置
              name: 'xiangqing',
              /*使用占位符声明,接收params参数,相当于说先占个位置,在路由组件中就可以按照位置进行参数传递*/
              // params方法传参配置
              // path: 'detail/:title/:works',
              // query方法传参配置
              path: 'detail',
              component: Detail,
              meta:{isAuth: true,title:'详情'},
			  //props的第三种写法,props值为函数,该函数返回的对象中每一组key-value都会通过props传给路由组件
			  // query方法传参配置
			  props($route) {
				return {
                    // works: $route.params.works,
                    title: $route.query.title,
                    works: $route.query.works,
                    a: 1,
                    b: 'hello',
                };
			  },
                // params方法传参配置
                /* props($route) {
                    return {
                       works: $route.params.works,
                       title: $route.params.title,
                       a:1,
                       b:'hello'
                    };
                }, */
			},
		  ],
		  },
		],
		},
	],
});

//全局前置路由守卫————初始化的时候被调用、每次路由切换之前被调用
router.beforeEach((to,from,next)=>{
  console.log('前置路由守卫',to,from)
  console.log('next函数',next)
   //判断是否需要鉴权
  if (to.meta.isAuth) {
    if (localStorage.getItem('userName') === 'xujianfei') {
      document.title =  to.meta.title
      next()
    }else{
      alert('用户名不对,无权限查看!')
    }
  }else{
    document.title =  to.meta.title
    next()
  }
})

export default router

全局后置钩子

  • 你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

  • 全局后置守卫,组件初始化时调用,每次路由切换之后调用,路由切换之后指的就是,举个例子说,当前我在A路由组件,我要切换到B路由组件,那么后置路由守卫就是在我点了切换按钮B路由组件呈现到页面中后被调用。

① 执行时间
初始化时执行,每次路由切换后执行
② 使用场景
对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。
③ 注意项
不会接受 next函数,也不会改变导航本身
④ 使用方法
可以使用 router.afterEach 注册一个全局后置守卫

const router = new VueRouter({ ... })

//全局后置路由守卫————初始化的时候被调用、每次路由切换之后被调用
router.afterEach( (to,from)=>{
  console.log('后置路由守卫',to,from)
  //修改网页的title
  document.title =  to.meta.title ||'小白学习路由守卫'
})

路由独享的守卫

  • 组件独享守卫是在进入组件时被调用,区别就在于,想对那个路由进行权限控制就直接在其路由配置项中添加守卫,作用域也仅限于该路由

① 执行时间
独享守卫 只在进入路由时触发,不会在 params、query 或 hash 改变时触发。它们只有在 从一个不同的 路由导航时,才会被触发。
② 注意项
独享守卫没有后置,可以全局后置路由守卫搭配使用
③ 使用方法
直接在路由配置上使用 beforeEnter定义独享守卫

你可以在路由配置上直接定义 beforeEnter 守卫:【逻辑判断也在beforeEnter里面写】


const routes = [
  {
    path: '/users/:id',
    component: UserDetails,
    beforeEnter(to,from,next){
        //逻辑判断写在此处
    },
  },
]

这些守卫与全局前置守卫的方法参数是一样的。

  • 全局路由守卫服务的是所有路由组件,而独享路由守卫只服务于被配置的单个路由组件

组件内的守卫

当使用路由规则进入该组件或离开该组件时,就会触发组件内守卫的调用,而组件内守卫的作用于范围也仅限于该组件

  • beforeRouteEnter
  • beforeRouteUpdate (2.2 新增)
  • beforeRouteLeave
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(vm => {
    // 通过 `vm` 访问组件实例
  })
}

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

beforeRouteUpdate (to, from, next) {
  // just use `this`
  this.name = to.params.name
  next()
}

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

beforeRouteLeave (to, from, next) {
  const answer = alert('还未保存,确定要离开吗')//放行
  if (answer) {
    next()//放行
  } else {
    next(false)//取消
  }
}

唯一不同于之前的就是:BeforeRouterLeave(),它并不像全局后置守卫一样在路由组件加载完成之后调用,而是在你切换出这个组件后被调用,也就是离开这个组件后被调用,在开发中,我们也可以使用BeforeRouterLeave() 来完成某些操作,比如当我要切换出该组件事,我希望该组件的操作能暂停,而不是一直运行,只有当我切换回该组件时,又再次运行,这样的操作就可以配合着beforeRouteEnter() 来完成,也可以提高应用的性能。

完整的导航解析流程

  1. 导航被触发。

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

  3. 调用全局前置守卫 beforeEach

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

    举例来说,对于一个带有动态参数的路径 /users/:id,在 /users/1/users/2 之间跳转的时候, 由于会渲染同样的 UserDetails 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。

  5. 在路由配置里调用 独享守卫beforeEnter

  6. 解析异步路由组件。

  7. 在被激活的组件里调用 进入守卫beforeRouteEnter

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

  9. 导航被确认。

  10. 调用全局后置守卫afterEach

  11. 触发 DOM 更新。

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

路由元信息

通过路由记录的 meta 属性可以定义路由的元信息。使用路由元信息可以在路由中附加自定义的数据,例如:

  1. 每个路由给予独立的标题;
  2. 管理后台的路由,部分页面需要限制一些访问权限;
  3. 通过路由来自动生成侧边栏、面包屑;
  4. 部分路由的生命周期需要做缓存( Keep Alive );
  5. 其他更多业务场景…

我们可以在导航守卫或者是路由对象中访问路由的元信息数据。

const routes = [
  {
    path: '/posts',
    component: PostsLayout,
    children: [
      {
        path: 'new',
        component: PostsNew,
        // 只有经过身份验证的用户才能创建帖子
        meta: { requiresAuth: true, title:'创建帖子'}
      },
      {
        path: ':id',
        component: PostsDetail,
        // 任何人都可以阅读文章
        meta: { requiresAuth: false ,title:'阅读文章'}
      }
    ]
  }
]

后续等vue2所有基础知识学完后,整个学习笔记的代码会上传到github文章来源地址https://www.toymoban.com/news/detail-605186.html

到了这里,关于前端vue入门(纯代码)35_导航守卫的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 编程式导航、缓存路由组件、路由守卫、Vue UI组件库【VUE】

    作用:不借助 router-link 实现路由跳转,让路由跳转更加灵活 具体编码: 作用:让不展示的路由组件保持挂载,不被销毁 具体编码: 作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。 具体名字: (1)activated路由组件被激活时触发 (2)deactivated路由组件失

    2024年02月03日
    浏览(36)
  • 路由缓存问题 | vue-router的导航守卫

             带参路由,当 参数发生变化时,相同的组件实例将被复用 ,组件的 生命周期钩子不会被调用, 导致 请求不会被重新发送, 以至于 数据无法更新 。 两种解决方法: 1. 给 RouterView绑定key值 ,即 特点:不复用,破坏组件缓存,强制执行,存在一定的 浪费 ,即

    2024年02月09日
    浏览(30)
  • React/Vue实现路由鉴权/导航守卫/路由拦截

    1、实现思路 自己封装  AuthRoute  路由鉴权高阶组件,实现未登录拦截,并跳转到登录页面 思路为:判断本地是否有token,如果有,就返回子组件,否则就重定向到登录Login 2、实现步骤 在 components 目录中,创建 AuthRoute/index.js 文件 判断是否登录 登录时,直接渲染相应页面组

    2024年02月15日
    浏览(29)
  • 20230706----重返学习-vue路由导航守卫相关-物美后台管理系统

    常见面试题 面试题:介绍一下 vue-router 中的导航守卫函数 面试题:介绍一下你对vue-router的理解? 导航守卫函数 面试题:介绍一下 vue-router 中的导航守卫函数 在每一次路由切换的时候,首先把路由匹配、导航确认等事宜先处理好-在此期间会触发一系列的钩子函数,这些函数

    2024年02月12日
    浏览(33)
  • Vue2路由:手动配置使用路由&路由嵌套、路由动态传参(:参数,query、props)、编程式导航(back、go)、导航守卫

    过了一遍vue2的router,整理一下小结 目录 一、前端路由的概念与原理 1.1 什么是路由 1.2 路由的工作方式 二、vue-router的基本使用 2.1 安装、配置、使用router 2.2 redirect重定向 三、嵌套路由 3.1 声明子路由的规则 3.2 默认子路由 四、动态路由 4.1 动态路由的概念 4.2 动态路由取参方

    2024年02月05日
    浏览(34)
  • 【前端】vue.js从入门到项目实战笔记

    【前端目录贴】 文本插值中的代码被解释为节点的文本内容,而HTML插值中的代码则被渲染为视图节点。 3.1.1 文本插值 文本插值的方式:用 双大括号 将要绑定的变量、值、表达式括住就可以实现,Vue将会 获取计算后的值 ,并以 文本的形式 将其展示出来。 结果: 3.1.2 HTM

    2024年01月21日
    浏览(39)
  • Vue2-replace属性、编程式路由导航、缓存路由组件、两个新的生命周期钩子、路由守卫、路由器工作模式

    🥔:如果事与愿违,那一定是上天另有安排 更多Vue知识请点击——Vue.js 1.作用:控制路由跳转时操作浏览器历史记录的模式 2.浏览器的历史记录有两种写入方式:分别为 push 和 replace , push是追加历史记录,replace是替换当前记录 。路由跳转时候 默认为push 3.如何开启replace模

    2024年02月10日
    浏览(40)
  • 前端vue入门(纯代码)11

    【 11.全局事件总线(Global Event Bus) 】 全局事件总线:实现任意组件间通信 【原理图】 结合上图,假若C组件想要传递数据给A组件,那么,就通过全局事件总线在A组件中绑定 【$on】 一个自定义事件demo,并界定一个参数来接收传递的数据,同样在C组件中,就需要通过全局事件

    2024年02月10日
    浏览(40)
  • 前端vue入门(纯代码)18

    不管何时何地,永远保持热爱,永远积极向上!!! 【 20.尚硅谷GitHub搜索案例_vue-resource实现 】 1.vue-resource vue-resource 是 vue 中一个用于发送请求的插件。 vue 发送请求推荐使用 axios ,vue-resource 的更新频率不高,且 vue 也推荐 axios。 1.1 安装插件vue-resource vue插件使用忘了的,

    2024年02月11日
    浏览(36)
  • 前端vue入门(纯代码)20

    总以为自己还很年轻,却忽略了岁月的脚步,当身边的一道道风景变成了回忆,才忽然发现,风景依然在,而人已非少年。!!! 【 22.求和案例--纯Vue版本 】 太简单了,直接上代码案例 App.vue Count.vue [【注意】 value=\\\"1\\\" :绑定的是一个字符类型,需要把它转换成number类型

    2024年02月12日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包