【Vue3从零开始-实战】S6:路由守卫实现登录校验功能

1,599 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情

前言

实战已经开始了!在前面几篇文章中,我们将首页的各个组件完成了,还将登录页的布局实现了。并且把路由配置完成了。在本篇文章中会使用路由守卫实现基础登录校验功能,为了循序渐进,复杂的方式会在后面的文章中完善。

全局路由守卫beforeEach

beforeEach:表示路由跳转时执行的函数。 🌀 比如我们的项目需要先登录,然后才能看到首页。但是现在我们打开根路由的时候,可以直接看到首页,并不需要登录。那么我们就可以在beforeEach函数中去判断一下。

👉 打开router目录下的index.js文件

image.png

👆 在创建路由之后使用beforeEach函数

router.beforeEach((to, from, next) => {
  console.log(to, from)
  next()
})

🔆 beforeEach函数中有一个回调函数,回调函数中接收三个参数:to、from、next

  • to:即将要进入的目标路由。
  • from:当前导航正在离开的路由。
  • next:可以理解为一个中间件,表示继续执行的方法。

next是一个函数,也是beforeEach中必须要调用的钩子函数。

image.png

⭕️ 在浏览器控制台中可以看到打印出来的内容里面都是路由配置中写到的:name、path等信息。

校验登录

既然beforeEach函数中可以在路由跳转之前执行,那么我们就可以在函数中判断一下是否有登录,如果有就继续执行跳转,否则就跳转到登录页。

router.beforeEach((to, from, next) => {
  if (isLogin) {
    next()
  } else {
    next({ name: 'Home' })
  }
})
  • next函数中接收一个对象,对象里面的name就是路由配置中的name,也是跳转路由的名称。

image.png

🚫 当我们访问根路由的时候,好像并没有校验登录,而是在控制台报错了。

⭕️ 这是因为路由守卫在执行过程中发现如果我们直接访问登录页的时候,也会校验isLogin,当它为false的时候,也会去访问登录页,这样就是一个死循环了。一直校验就会一直跳转登录页。

🔥 所以我们在判断是否登录的时候,还要顺便判断一下目标路由是否为登录页。

router.beforeEach((to, from, next) => {
  const isLogin = false
  if (isLogin || to.name === 'Login') {
    next()
  } else {
    next({ name: 'Login' })
  }
})
  • 在上面打印 to 的值时,里面也是有一个name,表示路由配置里面的名称。

Kapture 2022-06-17 at 23.13.04.gif

🔆 现在我们不管怎么操作路由,都会跳转到登录页了。

登录跳转

🌀 进入登录页已经校验成功了,下面就该点击登录跳转到首页去了。

👉 打开Login.vue文件。

image.png

☝️ 在Login.vue中给登录按钮一个点击事件

<div class="wrapper__login-button" @click="handleLogin">登陆</div>

✌️ 在js中引入useRouter用于路由跳转

import { useRouter } from 'vue-router'

👌 在setup中使用useRouter函数跳转到首页

setup () {
    const router = useRouter()
    const handleLogin = () => {
      router.push({ name: 'Home' })
    }
    return { handleLogin }
}

❗️最关键的一步就是要把beforeEach中的登录校验改为true,否则校验不成功就不会跳转的。

router.beforeEach((to, from, next) => {
  const isLogin = true
  if (isLogin || to.name === 'Login') {
    next()
  } else {
    next({ name: 'Login' })
  }
})

chrome-capture.gif

局部路由守卫beforeEnter

beforeEnter:表示加载到当前路由之前需要执行的钩子函数

😲 虽然我们在beforeEach函数中定义了isLogin = true,但是当我们在浏览器地址栏后面加上login路由时,还是会跳转到登录页。

Kapture 2022-06-18 at 16.19.19.gif

😫 这样登录就没有意义了,所以我们需要将isLogin的值存起来,方便我们后面判断。

  1. 在登录按钮点击事件中,将isLogin存储到localStorage
const handleLogin = () => {
  localStorage.isLogin = true
  router.push({ name: 'Home' })
}
  1. 在beforeEach 中通过获取localStorage中的isLogin来校验
router.beforeEach((to, from, next) => {
  const { isLogin } = localStorage
  if (isLogin || to.name === 'Login') {
    next()
  } else {
    next({ name: 'Login' })
  }
})
  1. 在路由配置中,login配置下面使用beforeEnter函数通过判断isLogin来校验是否需要进入登录页
const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  }, {
    path: '/login',
    name: 'Login',
    component: Login,
    beforeEnter (to, from, next) {
      const { isLogin } = localStorage
      isLogin ? next({ name: 'Home' }) : next()
    }
  }
]

Kapture 2022-06-18 at 16.30.00.gif

总结

本章节主要是将登录页和首页进行关联,并把路由中的钩子函数讲解了一点。

在登录的时候,我们并没有校验用户名和密码,因为重点不在这里,所以有兴趣的同学可以自己实现一下看看哦~