路由守卫

路由守卫就是在进入页面之前做一层判断,如果没有守卫,可以直接进入页面,如果添加了守卫,则需要做页面跳转。

例如有3个组件,分别是登录组件、商品详情组件、购物车组件。当用户单击商品详情时,可以直接进入页面,当单击购物车组件时,需要判断是否登录,如果登录即可进入购物车组件,如果没有登录则需要先跳转到登录页面。

路由守卫分为全局路由守卫、组件内路由守卫和离开组件时守卫。

全局路由守卫

打开 main.js,在 main.js 中添加下述代码。

router.beforeEach((to,from,next)=>{
    // to表示要去的新页面
    // from表示旧页面
    // next表示是否放行
    next()
})

代码解析如下。

router.beforeEach 表示开启路由守卫。

next 参数表示是否放行,不管有没有进行守卫判断都需要放行,否则会整体拦截页面。

创建 mylogin、mydetail、mycart 组件,实现上述案例,代码如下。

HelloWorld 组件中的视图层代码如下。

<div class="hello">
  <router-link to="/mydetail">商品详情</router-link>
  <router-link to="/mycart">购物车</router-link>
</div>

路由匹配规则代码如下。

export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
      path: '/mylogin',
      name: 'mylogin',
      component: mylogin
    },
    {
      path: '/mydetail',
      name: 'mydetail',
      component: mydetail
    },
    {
      path: '/mycart',
      name: 'mycart',
      component: mycart,
      meta: {
        needAuth: true
      }
    },
  ]
})

代码解析如下。

注意,进入购物车组件是需要进行路由判断的,所以购物车组件的匹配规则多了一个 meta 属性,meta 属性就是判断组件是否需要守卫的。

main.js 代码如下。

router.beforeEach((to, from, next) => {
  // to 表示要去的新页面
  // from 表示旧页面
  // next 表示是否放行
  var islogin = 0 // 0 表示未登录,1 表示已登录
  if (to.meta.needAuth) {
    if (islogin == 0) {
      router.push({ name: 'mylogin' })
    }
    if (islogin == 1) {
      next()
    }
  } else {
    // 如果没有 meta.needAuth 则直接放行
    next()
  }
})

代码解析如下。

声明 islogin 变量,0 表示未登录,1 表示已登录。运行程序,当单击购物车组件时会直接跳转到登录组件,实现守卫效果。

组件内路由守卫

7.10.1 节演示的是全局路由守卫,接下来介绍组件内路由守卫,新建订单组件 order.vue,进入订单组件时守卫,代码如下。

HelloWorld 视图层代码如下。

<router-link to="/order">订单</router-link>

路由匹配规则如下。

{
  path: '/order',
  name: 'order',
  component: order
}

组件内守卫不需要 meta 属性。

order.vue 代码如下。

<template>
  <h1>订单组件</h1>
</template>

<script>
export default {
  beforeRouteEnter: (to, from, next) => {
    var islogin = 0; // 0 表示未登录,1 表示已登录
    if (islogin == 0) {
      // 跳转到购物车页面
      // 不能使用 router 跳转,应该使用 next 跳转
      next({ name: "mycart" });
    } else {
      next();
    }
  }
};
</script>

代码解析如下。

同样声明 islogin 变量,判断是否登录。注意,路由跳转需要用到 next() 方法跳转,不能使用 router.push() 方法进行跳转。

运行程序,单击订单组件,由于 islogin 的值是 0,表示没有登录,因此会直接跳转到登录组件。

离开组件时守卫

7.10.2 节演示的是进入组件时守卫,Vue 还提供了离开组件时守卫,例如从订单组件返回到 HelloWorld 组件,代码如下。

<template>
  <h1>订单组件</h1>
</template>

<script>
export default {
  // 进入组件时守卫
  // 1. islogin 设置为 1,表示已登录,先进入组件
  beforeRouteEnter: (to, from, next) => {
    var islogin = 1;
    if (islogin == 0) {
      next({ name: "mycart" });
    } else {
      next();
    }
  },
  // 离开组件时守卫
  beforeRouteLeave: (to, from, next) => {
    // 2. 离开组件时弹出对话框
    if (confirm('是否离开页面?')) {
      next();
    } else {
      next(false); // 阻止离开
    }
  }
};
</script>

代码解析如下。

  • 首先进入订单组件,要把 islogin 的值修改为 1。

  • 离开组件时,设置对话框提醒,运行结果如图 7-8 所示。

image 2025 02 11 16 37 01 681
Figure 1. 图7-8 离开组件触发守卫