Vue--》深入理解 Vue 3 导航守卫,掌握前端路由的灵魂技能!

news2024/11/24 10:44:37

目录

vue3导航守卫讲解与使用

element-ui的安装与使用

配置路由和设置路径别名

设置登录页面并实现规则跳转

设置导航前置守卫

设置导航后置守卫

其他路由相关操作


vue3导航守卫讲解与使用

导航守卫是在 Vue Router 中提供的一种功能,它允许你在切换路由之前或之后执行一些逻辑。通过使用导航守卫,你可以控制用户是否可以访问路由、重定向、记录路由进入记录等。在 Vue Router 下,导航守卫包括全局守卫、路由独享守卫、组件内守卫,这些守卫可以用来完成不同层次的路由钩子函数。

今天借助讲解导航守卫的这篇文章讲解一个登录页面的案例,详细说明在日常开发过程中应该如何灵活的运用和操作这些函数,这里借助vue组件库 element-ui 进行润色,话不多说直接开整。

element-ui的安装与使用

找到element-ui官网:官方网址 ,然后终端执行如下命令安装第三方包:

# 选择一个你喜欢的包管理器
# NPM
$ npm install element-plus --save
# Yarn
$ yarn add element-plus
# pnpm
$ pnpm install element-plus

安装完成之后,在入口文件 mian.ts 进行插件的挂载:

import { createApp } from 'vue'
import App from './App.vue'
import {router} from "./router"
import ElementUi from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App)
app.use(router)
app.use(ElementUi)

app.mount('#app')

注意:如果您使用 Volar,请在 tsconfig.json 中通过 compilerOptions.type 指定全局组件类型。

// tsconfig.json
{
  "compilerOptions": {
    // ...
    "types": ["element-plus/global"]
  }
}

挂载完成之后,随便在官网上粘一段代码,如下查看效果是否被引入:

配置路由和设置路径别名

在router文件夹下的index.ts文件添加如下代码进行配置路由:

import { createRouter, createWebHistory } from 'vue-router'

export const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path:'/',
      component:()=>import('@/components/login.vue')
    },
    {
      path:"/index",
      component:()=>import("@/components/index.vue")
    }
  ],
})

设置路径别名: 如果想在vite创建的vue3+ts项目中进行路径别名配置的话可以参考如下方式:

1)安装@types/node包提供了 Node.js 中核心模块的 TypeScript 类型声明:

npm install --save-dev @types/node

2)安装完成之后,进行 vite.config.ts 文件配置,如下 :

import { fileURLToPath,URL } from 'url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve:{
    alias:{
      '@':fileURLToPath(new URL('./src',import.meta.url))
    }
  }
})

3)在tsconfig.json文件进行如下路径配置:

{
  "compilerOptions": {
    // ...
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  },
  // ...
}

设置登录页面并实现规则跳转

制作登录界面:根据上文设置的element-ui组件库,接下来借助该组件库制作一个简易的登录界面,如下:

<template>
  <div class="login">
    <el-card class="box-card">
      <el-form :model="formInline" class="demo-form-inline">
        <el-form-item label="账号:">
          <el-input v-model="formInline.user" placeholder="请输入账号" />
        </el-form-item>
        <el-form-item label="密码:">
          <el-input v-model="formInline.password" placeholder="请输入密码" type="password" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onSubmit" style="width: 100%">登录</el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>
<script setup lang="ts">
import { reactive } from 'vue'
import { useRouter } from 'vue-router';
type Form = {
  user:string,
  password:string
}

const router = useRouter()
const formInline = reactive<Form>({
  user: '',
  password: '',
})

const onSubmit = () => {
  router.push('/index')
}

</script>
<style lang="less" scoped>
.login {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
}
</style>

输入框验证:根据上文呈现的登录页面的效果,接下来给登录框添加规则校验,如下:

import type { FormRules } from 'element-plus'
// 给登录框设置规则校验
const rules = reactive<FormRules>({
  user:[
    {
      required:true,
      message:"请输入用户名",
      type:"string",
      trigger:"blur"
    }
  ],
  password:[
    {
      required:true,
      message:"请输入密码",
      type:"string",
      trigger:"blur"
    }
  ]
})

设置完校验代码之后,给form添加rule规则,并且给每一个要规则校验的item添加对应的prop:

设置导航前置守卫

beforeEach:是Vue Router中的导航守卫之一,它用于在路由切换之前执行一些逻辑操作,例如检查用户是否登录或者获取一些路由需要的数据。它可以被用于全局,也可以用于单个路由或者路由组件中。当导航被触发时,它会按照它们添加的顺序依次被调用。如果其中任何一个导航守卫返回 false 或者是一个 Promise 并且被 reject,则导航会被取消。

我们先通过ref获取登录框的相关属性值:

然后给按钮设置点击事件,判断用户有没有输入用户名和密码,输入了就在浏览器本地存储个token,如下:

const onSubmit = () => {
  form.value?.validate((validate)=>{
    if(validate){
      router.push('/index')
      localStorage.setItem('token','success')
    }else{
      ElMessage.error("请输入用户/密码")
    }
  })
}

接下来可以在入口文件 main.ts 处设置前置守卫的代码了,根据如下代码的效果就可以实现在未登录的情况下是不能直接访问我们后台 index 路径下的路由的,登录之后会存放一个token,有token之后就可以直接访问后台 index 页面的内容了。

// 设置白名单
const whiteList = ['/']
// 设置路由前置守卫
router.beforeEach((to,from,next)=>{
  if(whiteList.includes(to.path) || localStorage.getItem("token")){
    next()
  }else{
    next('/')
  }
})

设置导航后置守卫

afterEach:是 Vue Router 提供的一个全局守卫,它会在用户完成导航后被触发,无论是通过用户操作还是通过编写代码实现的导航。与 beforeEach 不同,afterEach 主要用于处理用户的导航完成之后需要进行的操作,例如页面统计、数据收集、用户行为分析等。

afterEach函数接收两个参数:to 和 from,分别表示目标路由和来源路由。我们可以在这个函数内部完成一些异步操作,例如向服务器发送统计数据、记录用户行为等,并在完成后更新页面的相关状态。

这里可以设置一个网页的进度条,在网页内容最顶部设置一个进度条来显示页面的加载程度,这里我将进度条单独抽离出一个组件:

<template>
  <div class="wraps">
    <div ref="bar" class="bar"></div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
let speed = ref<number>(1)
let bar = ref<HTMLElement>()
let timer = ref<number>(0)
const startLoading = ()=> {
  speed.value = 1
  let dom = bar.value as HTMLElement
  timer.value = window.requestAnimationFrame(function fn(){
    if(speed.value < 90){
      speed.value+=1
      dom.style.width = speed.value + '%'
      timer.value = window.requestAnimationFrame(fn)
    }else{
      speed.value = 1
      window.cancelAnimationFrame(timer.value)
    }
  })
}
const endLoading = () => {
  let dom = bar.value as HTMLElement
    setTimeout(()=>{
      window.requestAnimationFrame(()=>{
      speed.value = 100
      dom.style.width = speed.value + '%'
    })
  },1000)
}
defineExpose({
  startLoading,
  endLoading
})
</script>

<style lang="less" scoped>
.wraps{
  position: fixed;
  top: 0;
  width: 100%;
  height: 2px;
  .bar{
    height: inherit; // 继承父级高度
    width: 0;
    background: red;
  }
}
</style>

接下来在入口文件 main.ts 处设置导航后置守卫的内容:

注意:createVNode 是 Vue3 中的一个函数,用于创建一个虚拟节点,也就是 VNode 对象。它的作用是将模板编译成 VNode 对象,这个对象包含了节点的类型、属性、事件、子节点等信息,便于虚拟 DOM 操作和渲染。而且,相比较于 Vue2,Vue3 中的 createVNode 更加灵活和高效,可以手动地创建任何类型的节点,包括元素节点、组件节点、文本节点等。

其他路由相关操作

路由元信息:路由元信息指的是在 Vue Router 中,可以在路由配置中添加一些自定义信息,这些信息可以在路由组件中使用。通常包含了一些与路由相关的数据,例如当前路由的标题、面包屑等等。路由元信息可以在全局路由守卫中进行访问、修改和添加,也可以在单个路由配置中进行访问、修改和添加。

import { createRouter, createWebHistory } from 'vue-router'

export const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path:'/',
      component:()=>import('@/components/login.vue'),
      meta:{
        title:"登录页面"
      }
    },
    {
      path:"/index",
      component:()=>import("@/components/index.vue"),
      meta:{
        title:"首页!!!"
      }
    }
  ],
})

在入口文件 mian.ts 处的前置路由守卫进行标题设置:

最后浏览器的网页标题就会动态的随着路由路径的切换而变化。

路由过渡动效:在路由中我们可以设置动画过渡效果,这里可以借助第三方动画库 animate ,具体的动画库的详细操作,我在之前的文章已经讲解过了:Vue--》实现动画与过渡效果 ,这里就不再赘述,仅仅展示如何使用:

在根App.vue组件处设置插槽来进行属性的引入:

<template>
  <router-view #default="{route,Component}">
    <transition :enter-active-class="`animate__animated ${route.meta.transition}`">
      <component :is="Component"></component>
    </transition>
  </router-view>
</template>

<script setup lang="ts">
import "animate.css"
</script>

 具体效果如下:

scrollBehavior:是Vue Router提供的一个钩子函数,用于控制路由跳转时页面滚动的行为。该函数接收三个参数,分别是 to、from 和 savedPosition。其中to和from都是路由对象,savedPosition 是一个位置对象,记录了页面跳转前的滚动条位置。

scrollBehavior 函数需要返回一个位置对象,用于指定页面跳转后的滚动条位置。例如,可以使用以下代码实现页面跳转时滚动到页面顶部:

const router = new VueRouter({
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    return { x: 0, y: 0 };
  }
})

除了返回一个对象以外,还可以返回一个 Promise 对象,以支持异步操作。例如,可以使用以下代码实现页面跳转时滚动到具有指定 ID 的元素处:

const router = new VueRouter({
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    if (to.hash) {
      return new Promise(resolve => {
        setTimeout(() => {
          resolve({ selector: to.hash });
        }, 100);
      });
    } else {
      return { x: 0, y: 0 };
    }
  }
})

具体实现效果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/549546.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能Python-pythonfirst

PythonFirst&#xff1a;Python编程新手的最佳起点 作为一门简洁而又强大的编程语言&#xff0c;Python在过去的几年中得到了越来越多的关注和应用。它广泛应用于数据分析、人工智能、Web开发、自动化等领域&#xff0c;成为了许多程序员的首选语言。如果你也是刚刚开始接触Py…

有哪些简单而知道的人少的excel操作技巧?

以下是 Excel 里鲜为人知而又简单、逆天的操作技巧&#xff1a; 1. 快速选中数据区域&#xff1a;双击数据区域左上角的方格即可快速选中整个数据区域。 2. 使用自动筛选快速查找和筛选数据&#xff1a;在 Excel 数据表中&#xff0c;使用自动筛选可以快速找到和筛选特定数据…

【Robot Dynamics Lecture Notes学习笔记之浮动基动力学】

Robot Dynamics Lecture Notes学习笔记之浮动基动力学 Contact ForcesSoft Contact Model Contact Forces from Constraints Constraint Consistent DynamicsContact Switches and Impact CollisionsImpulse TransferEnergy Loss 浮动基座系统的广义坐标分别由驱动关节坐标 q j…

小程序-基础加强(二):使用npm包

使用npm包 1.小程序对npm的支持与限制 目前&#xff0c;小程序中已经支持使用npm安装第三方包&#xff0c;从而来提高小程序的开发效率。但是&#xff0c;在小程序中使用npm包有如下3个限制&#xff1a; ①不支持依赖于Node.js内置库的包 ②不支持依赖于浏览器内置对象的包 …

Springboot +spring security,登录表单进阶配置及原理分析

一.简介 登录表单配置实操 二.创建项目 如何创建一个SpringSecurity项目&#xff0c;前面文章已经有说明了&#xff0c;这里就不重复写了。 三.配置默认用户信息 配置文件添加如下用户信息&#xff0c;代码如下&#xff1a; spring:security:user:name: lglbcpassword: 1…

HNU数据结构与算法分析-作业7-算法设计技术

1. (简答题, 10分)请简述分治法所能解决的问题一般具有哪些特征&#xff1f; 2. (简答题, 10分)请简述动态规划法的四个求解步骤。 3. (简答题, 10分)请比较动态规划法和贪心法&#xff0c;并写出两者的区别。 4. (简答题, 10分)请写出分支限界法和回溯法的区别。 二. 算法设计…

chatgpt赋能Python-pythonendswith

Python endswith方法&#xff1a;介绍、用法和示例 在编程中&#xff0c;经常需要查找字符串是否以特定字符结尾。Python提供了一个方便易用的方法——endswith()。 什么是Python endswith()方法&#xff1f; Python endswith()方法是用于检查字符串是否以特定子字符串结尾的…

第六章总结-莫凡商城的注册、登录功能

1.微信小程序表单组件 1.1button按钮组件 type的属性值有三种 primary 绿色default 白色warn 红色 除了这种方式可以设置按钮大小&#xff0c;还有其他的通过视图来控制按钮的方式&#xff0c;因为我们知道&#xff0c;微信小程序的按钮并不都是这三种颜色。其他方式比如把按…

Web APIs之DOM

一.Web API基本认知 二.获取DOM对象 三.操作元素内容 四. 操作元素属性 五.定时器-间歇函数 一、Web API基本认知 *作用和分类 *什么是DOM *DOM树 *DOM对象 1.作用和分类 &#xff08;1&#xff09;作用&#xff1a;使用JS去操作html和浏览器 &#xff08;2&#xff09…

service mesh学习

背景 单体服务的痛点导致单体服务被拆分为多个微服 每个微服必须要解决负载均衡、服务发现、熔断等功能 为了让上层开发更加快速和无需关注通用能力&#xff0c;在网络栈和应用业务层之间抽出一个透明网络代理层。 Service Mesh 轻量级网络代理&#xff0c;负责微服之间的通…

H5 实现蜂巢(六边形)导航,支持用户交互和动态添加,纯css实现无需布局计算

最近公司的项目出了版新的UI设计图&#xff0c;所以准备进行样式改版 而其中就有个导航要改成蜂巢(六边形)导航&#xff0c;当我看到时其实也挺迷糊的。 说一下我一开始的想法哈&#xff1a; 我一开始是打算使用背景颜色线性渐变 或者 用4个子元素覆盖4角 来实现 六边形的视觉…

二、数据字典开发

文章目录 二、数据字典开发1、搭建service-cmn模块1.1 搭建service-cmn模块1.2 修改配置1.3 启动类 2、数据字典列表2.1 数据字典列表接口2.1.1 model模块添加数据字典实体2.1.2 添加数据字典mapper2.1.4 添加数据字典controller 2.2 数据字典列表前端2.2.1 添加路由2.2.2 定义…

centos 8 安装nacos2.0.3

去官网下载软件包 下载地址&#xff1a;https://github.com/alibaba/nacos/releases 上传到服务器指定位置&#xff0c;并解压 修改nacos存储为数据库 vi /xxx/nacos/conf/application.properties ## 在最后添加以下内容 spring.datasource.platformmysql db.num1 db.url.0j…

chatgpt赋能Python-pythonend

Pythonend – 一站式 Python SEO 工具 Pythonend 是一款基于 Python 的 SEO 工具&#xff0c;它为企业和个人提供了一站式的 SEO 解决方案。无论您是想要提高网站排名、监测关键词排名、分析竞争对手或进行网站优化&#xff0c;Pythonend 都可以帮助您解决这些问题。 Pythone…

【Linux】——进程信号

目录 信号入门 生活的角度 技术应用的角度 信号列表 信号处理常见方式概览 信号产生 通过终端按键产生信号 核心转储 调用系统函数向进程发信号 由软件条件产生信号 SIGPIPE信号 SIGALRM信号 硬件异常产生信号 阻塞信号 信号其他相关常见概念 内核中…

软件测试:测试用例

一、通用测试用例八要素  1、用例编号&#xff1b;   2、测试项目&#xff1b;   3、测试标题&#xff1b;   4、重要级别&#xff1b;   5、预置条件&#xff1b;   6、测试输入&#xff1b;   7、操作步骤&#xff1b;   8、预期输出 二、具体分析通用测试用…

红帽6.5进入单用户重置root密码

前言 ​一、重启Linux系统 二、按 “e” 键进入该界面 三、上下键选中第二个kernel选项&#xff0c;继续按 “e” 键进行编辑。 五、根据提示按下按键“b”&#xff0c;进入单用户模式引导 六、进入到单用户模式&#xff0c;修改密码 七、重启系统 八、进行登录 前言 大…

图片转excel表格,人工处理与OCR方案的优劣对比

随着信息化进程的发展&#xff0c;我们常常需要将图片文件中的表格信息转换成Excel表格文件&#xff0c;并进行后续数据处理和分析。对于这一需求&#xff0c;常用的解决方案有人工录入和OCR识别两种方式。本文将对这两种方案进行比较&#xff0c;评估其优劣。 一、人工做表并…

二、MongoDB入门

文章目录 一、MongoDB入门1、常用操作1.1 INSERT1.2 Query1.3 Update1.4 Remove1.5 aggregate1.5.1 插入数据1.5.2 统计sum1.5.3 常见的聚合表达式 1.6 索引 一、MongoDB入门 1、常用操作 1.1 INSERT > db.User.save({name:zhangsan,age:21,sex:true}) > db.User.find…