当前位置: 首页>后端>正文

第三十七节-Vue路由-Vue-router路由(导航)守卫

1. 修改标题需求

1.1 需求

需求: 在SPA应用中,如何改变网页的标题

分析:

  1. 网页的标题是通过title标签来显示的,
  2. 但是在SPA应用中只有一个固定HTML,因此切换组件,标题不会改变
  3. 可以通过JavaScript 来修改title标签的内容, 通过window.document.title修改
1.2 解决方案

思路:

  1. 先前讲过生命周期,在进行路由跳转时,会进行组件显示的切换
  2. 每一个组件都会经历组件自己的生命周期
  3. 离开的组件组件会被销毁,
  4. 进入当前路由的组件,会经历组件的创建与挂在
  5. 因此我们可以了利用生命周期的钩子函数配合document修改title

示例代码:

Home组件

<script>
    export default {
        name:"Home",
        created(){
            document.title = "首页"
        }
    }
</script>

解决方法分析:

  1. 这样就需要我们在每一个页面组件都需要手动修改title内容
  2. 如果页面组件过多,在开发和后期维护上都是一个麻烦

思考:

  1. 就像咱们axios拦截功能一样,我们也需要一个拦截
  2. 这个拦截可以知道我们路由跳转是从哪个组件跳转到哪一个组件
  3. 这样我们就可以通过你将要去哪个路由,让title显示哪个路由中对于的标题信息

这就是我们将要学习的全局导航守卫.

2. 全局导航守卫

2.1 什么是导航守卫

导航守卫说的通俗一点,就在在路由跳转在中间添加的一层拦截,

说明:

  1. vue-router提供的导航的导航守卫主要用来监听路由的进入和离开
  2. vue-router提供了beforeEachafterEach钩子函数,会在路由跳转前和跳转后触发
2.2 导航守卫的钩子函数

vue-router提供了两个全局导航守卫

  1. beforeEach全局守卫, 也叫作前置守卫
  2. afterEach全局守卫, 也叫后置守卫,

导航守卫钩子函数的参数是一个回调函数,

2.2.1 beforeEach全局守卫

beforeEach全局守卫的回调函数接受三个参数,为to,from,next

三个参数说明:

  1. to 跳转进入的目标路由对象
  2. form当前准备离开的路由对象
  3. next 调用该方法后,进入下一个钩子, 作用类似于express或者koa中中间件里调用的next

next函数使用说明

  1. 如果next函数正常调用next()表示正常进入跳转路由,导航状态为确认
  2. 如果next函数在调用是传入false,如next(false), 表示终端导航跳转
  3. next函数还可以传参,表示跳转到指令路由next("/"),或next({path:"/"})参数的路由,

等着咱们看示例使用

2.2.2 afterEach`全局守卫

afterEach全局守卫的回调函数接受二个参数,为to,from

两个个参数说明:

  1. to 跳转进入的目标路由对象
  2. form当前准备离开的路由对象

为什么afterEach没有next参数呢,因为在afterEach被调用时, 路由已经跳转完毕,

2.3 使用全局守卫修改标题
2.3.1 使用全局守卫说明

使用全局守卫修改标题说明:

  1. 因为全局导航守卫回调函数参数to,form表示的是路由对象,
  2. 因此如过想在路由对象中获取title值,就必须现在路由映射中定义title
  3. title定义在meta元数据对象中, 元数据修饰数据的数据
  4. 在跳转路由是通过跳转路由获取title值,然后修改页面标题
2.3.2 修改路由

修改路由,添加title数据

{
    path:'/home',
    component: Home,
    meta:{title:"首页"}, // 元数据中添加title信息
},

2.3.3 在全局守卫中修改标题
// 使用全局导航守卫
router.beforeEach((to,from,next) => {
  // to 就是将要去的路由, 就是$route 对象
  // from 是离开的路由, 就是之前显示路由 也是$route 对象
  // console.log(to);
  // console.log(from);

  document.title = to.matched[0].meta.title
  next()

})

3. 路由独享守卫

3.1 路由独享守卫说明:
  1. 使用的钩子函数与全局导航守卫一致,为beforeEnter
  2. 不同的是:路由独享守卫是定义在路由记录中,全局导航守卫是定义在入口文件中
  3. 路由独享守卫只在当前路由进入时有效,全局导航守卫是所有路由跳转都会被拦截
3.2 例如:

现在只想拦截进入/离开/article路由,就可以给/article路由使用路由独享守卫

{
    path:'/article',
    component: Article,
    meta:{title:"文章"},
        beforeEnter(to,from,next){
            // 当路由跳转到/article是触发路由独享守卫
            console.log(to);
            console.log(from);
            console.log(next);
            next()
        },
},

4. 组件内的路由守卫

除了在全局和确定的路由中定义路由导航守卫,还可以在组件中定义路由导航守卫

4.1 组件内的路由守卫说明
  1. 组件内的守卫是定义在组件内部,组件选项对象中的路由守卫
  2. 组件内路由守卫有三个,为:beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave
  3. beforeRouteEnter组件创建前调用,不能使用组件实例this
  4. beforeRouteUpdate路由被改变,但是组件被复用时调用,比如动态路由
  5. beforeRouteLeave导航离开该组件时调用
4.2 例如

在文章组件中使用组件内的路由守卫

<script>
    export default {
        name:"Article",
        beforeRouteEnter(to,from,next){
            // 不!能!获取组件实例 `this`
            // 因为当守卫执行前,组件实例还没被创建
            next()
        },
        beforeRouteUpdate(to,from,next){
            // 在当前路由改变,但是该组件被复用时调用
            // 带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
            // 由于会渲染同样的 Article 组件,
            // 因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
            // 可以访问组件实例 `this`
            next()
        },
        beforeRouteLeave(to,from,next){
             // 导航离开该组件的对应路由时调用
             // 可以访问组件实例 `this`
            next()
        }

    }
</script>

4.3 关于组件内路由守卫的next参数

说明:

  1. next是一个函数,
  2. 因为在beforeRouteEnter路由守卫中不能通过this访问组件实例
  3. 因此在beforeRouteEnter守卫中next可以接受一个回调函数,回调函数的形参就是组件实例
  4. beforeRouteUpdatebeforeRouteLeave中能通过this获取组件实例,固不支持回调函数

https://www.xamrdz.com/backend/3vp1945684.html

相关文章: