【Vue-Router】导航守卫

前置守卫

main.ts

import { createApp } from 'vue'
import App from './App.vue'
import {router} from './router'
// import 引入
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const app = createApp(App)
app.use(router)
// use 注入 ElementPlus 插件
app.use(ElementPlus)const whiteList = ['/']// beforeEach 可以定义不止一个,vue会收集所有定义的路由钩子,所以next的作用不应该是跳转,而是使步骤进行到下一个你定义的钩子
router.beforeEach((to, from, next) => {// token每次都要跟后端校验一下是否过期if(whiteList.includes(to.path) || localStorage.getItem('token')){next()}else{next('/')}
})
app.mount('#app')

在这里插入图片描述

index.ts

import { createRouter, createWebHistory } from 'vue-router'export const router = createRouter({// import.meta.env.BASE_URL 应用的基本 URL。基本 URL 是指在你的应用部署到某个域名或子路径时,URL 的起始部分。例如,如果你的应用部署在 https://example.com/myapp/ 这个路径下,那么 import.meta.env.BASE_URL 就会是 /myapp/。history: createWebHistory(import.meta.env.BASE_URL),routes: [{path: '/',component: () => import('@/views/Login.vue'),},{path: '/index',component: () => import('@/views/Index.vue'),},],
})

App.vue

<template><router-view></router-view>
</template><script setup lang="ts"></script><style>
/* 注意 style 标签 别加 scoped 不然设置宽高不生效 */
* {margin: 0;padding: 0;
}
html, body, #app {height: 100%;overflow: hidden;
}
</style>

Login.vue

<template><div class="login"><el-card class="box-card"><el-form ref="form" :rules="rules" :model="formInline" class="demo-form-inline"><el-form-item prop="user" label="账号:"><el-input v-model="formInline.user" placeholder="请输入账号" /></el-form-item><el-form-item prop="password" label="密码:"><el-input v-model="formInline.password" placeholder="请输入密码" type="password"></el-input></el-form-item><el-form-item><el-button type="primary" @click="onSubmit">登录</el-button></el-form-item></el-form></el-card></div>
</template><script setup lang="ts">
import { reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import type { FormItemRule, FormInstance } from 'element-plus';
import { ElMessage } from 'element-plus'const router = useRouter()
type Form = {user: string,password: string
}
type  Rules = {[k in keyof Form]?: Array<FormItemRule>
}
const formInline = reactive<Form>({user: '',password: '',
})
const form = ref<FormInstance>()
const rules = reactive({user: [{required: true,message: '请输入账号',type: 'string',}],password: [{required: true,message: '请输入密码',type: 'string',}]
})const onSubmit = () => {console.log('submit!', form.value)form.value?.validate((validate)=>{if (validate) {router.push('/index')localStorage.setItem('token', '1')} else {ElMessage.error('账号或密码错误')}})}
</script><style scoped lang="less">
.login {height: 100%;display: flex;justify-content: center;align-items: center;
}
</style>

在这里插入图片描述

刚开始未登录过,不能使用输入 /index 的方式跳转,localStorage 不能读取 token

在这里插入图片描述

登录之后可以使用输入 /index 的方式跳转,localStorage 已存储 token

在这里插入图片描述

后置守卫

注册全局后置钩子,和前置守卫不同,这些钩子不会接受 next 函数,也不会改变导航本身。

例如:添加一个加载进度条功能

在这里插入图片描述
loadingBar.vue

<template><div class="wraps"><div ref="bar" class="bar"></div></div>
</template><script setup lang="ts">
import { ref, onMounted } from 'vue'
let speed = ref<number>(1)
let bar = ref<HTMLElement>()
let timer = ref<number>(0)
const startLoading = () => {speed.value = 1let dom = bar.value as HTMLElementtimer.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 = 1window.cancelAnimationFrame(timer.value)}})
}
const endLoading = () => {let dom = bar.value as HTMLElementsetTimeout(() => {window.requestAnimationFrame(() => {speed.value = 100dom.style.width = speed.value + '%'})}, 500)}defineExpose({ startLoading, endLoading })
</script><style scoped lang="less">
.wraps {width: 100%;position: fixed;height: 10px;top: 0;.bar {height: inherit;width: 0;background-color: #409eff;}
}
</style>

main.ts

import { createApp,createVNode,render } from 'vue'
import App from './App.vue'
import {router} from './router'
// import 引入
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import loadingBar from './components/loadingBar.vue'const Vnode = createVNode(loadingBar)
render(Vnode,document.body)
const app = createApp(App)
app.use(router)
// use 注入 ElementPlus 插件
app.use(ElementPlus)const whiteList = ['/']// beforeEach 可以定义不止一个,vue会收集所有定义的路由钩子,所以next的作用不应该是跳转,而是使步骤进行到下一个你定义的钩子
router.beforeEach((to, from, next) => {Vnode.component?.exposed?.startLoading()// token每次都要跟后端校验一下是否过期if(whiteList.includes(to.path) || localStorage.getItem('token')){next()}else{next('/')}
})router.afterEach((to, from) => {Vnode.component?.exposed?.endLoading()
})
app.mount('#app')

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

ShowMeBug CEO李亚飞受邀参加深圳青年创新创业系列沙龙电子信息专场

7月13日下午&#xff0c;由深圳市科技交流服务中心&#xff08;深圳市科技专家委员会办公室&#xff09;主办&#xff0c;深圳新一代产业园承办的“2023深圳青年创新创业系列沙龙——电子信息专场”活动举行。ShowMeBug CEO李亚飞受邀参加此次活动。 深圳市科学技术协会党组成员…

微信小程序真机调试异常cmdId 1006, errCode-50011-已解决

cmdId 1006, errCode-50011 起因 小程序在模拟器上预览没问题,真机调试和体验版首页打不开,点展开显示cmdId 1006, errCode-50011 解决 查了下1006, 说是广告, 我没接广告,这个也不是错误码 1006广告组件被驳回你的广告正在被审核,无法展现广告后来找到几个类似的帖子…

元宇宙时代超高清视音频技术白皮书关于流媒体协议和媒体传输解读

流媒体协议 元宇宙业务场景对流媒体传输的实时性和互动性提出了更高的要求&#xff0c;这就需要在传统的 RTMP、SRT、 HLS 等基础上增加实时互动的支持。实时互动&#xff0c;指在远程条件下沟通、协作&#xff0c;可随时随地接入、实时地传递虚实融合的多维信息&#xff0c;身…

万宾燃气管网监测解决方案,守护城市生命线安全

方案背景 城市燃气管网作为连接天然气长输管线与天然气用户的桥梁&#xff0c;担负着向企业和居民用户直接供气的重要职责。随着城市燃气需求的急剧增加&#xff0c;城市燃气管网规模日趋庞大&#xff0c;安全隐患和风险也随之增加。目前&#xff0c;我国燃气管网的运行仍存在…

Mathematica(42)-计算N个数值的和

比如&#xff0c;我们要用Mathematica求得到下面的式子&#xff1a; 这就需要用到一个函数&#xff1a;Sum 具体地&#xff0c;Sum函数的使用形式如下&#xff1a; 因此&#xff0c;按照公式就可以得到下面的结果&#xff1a; 如果&#xff0c;我们想要将求和号也加进去&#…

【AIGC 讯飞星火 | 百度AI|ChatGPT| 】智能对比

AI智能对比 &#x1f378; 前言&#x1f37a; 概念类对比&#x1f375; 讯飞&#x1f375; 百度AI&#x1f375; chatGPT &#x1f379; 功能类对比☕ 讯飞☕ 百度AI☕ chatGPT &#x1f943; 可输入字数对比&#x1f964; 百度AI&#x1f964; 讯飞&#x1f964; chatGPT &…

【Django】Task1安装python环境及运行项目

【Django】Task1安装python环境及运行项目 写在最前 8月份Datawhale组队学习&#xff0c;在这个群除我佬的时代&#xff0c;写一下blog记录学习过程。 参考资源&#xff1a; 学习项目github&#xff1a;https://github.com/Joe-2002/sweettalk-django4.2 队长博客&#xff1a…

RocketMQ 消息消费 轮询机制 PullRequestHoldService

1. 概述 先来看看 RocketMQ 消费过程中的轮询机制是啥。首先需要补充一点消费相关的前置知识。 1.1 消息消费方式 RocketMQ 支持多种消费方式&#xff0c;包括 Push 模式和 Pull 模式 Pull 模式&#xff1a;用户自己进行消息的拉取和消费进度的更新Push 模式&#xff1a;Broker…

探索心律失常:病因、诊断与治疗以及与肠道菌群的关联

谷禾健康 你是否有时会感到心悸、心慌、胸闷、气短、头晕、乏力&#xff1f;你是否有时感觉自己的心跳过快或过慢&#xff1f; 如果有上述情况&#xff0c;就要引起重视了&#xff0c;你可能存在心律失常。心律失常是最常见的心脏疾病之一&#xff0c;涉及到心脏的电活动节奏异…

麻辣烫数据可视化,麻辣烫市场将持续蓬勃发展

麻辣烫&#xff0c;这道源自中国的美食&#xff0c;早已成为人们生活中不可或缺的一部分。它独特的香辣口味&#xff0c;让人忍不住每每流连忘返。与人们的关系&#xff0c;简直如同挚友一般。每当寒冷的冬日或疲惫的时刻&#xff0c;麻辣烫总是悄然走进人们的心房&#xff0c;…

i.MX6ULL开发板无法进入NFS挂载文件系统的解决办法

问题 使用NFS网络挂载文件系统后卡住无法进入系统。 解决办法 此处不详细讲述NFS安装流程 查看板卡挂载在/home/etc/rc.init下的自启动程序 进入到../../home/etc目录下&#xff0c;查看rc.init文件&#xff0c;首先从第一行排查&#xff0c;查看/home/etc/netcfg文件代码内容&…

Flask-SQLAlchemy

认识Flask-SQLAlchemy Flask-SQLAlchemy 是一个为 Flask 应用增加 SQLAlchemy 支持的扩展。它致力于简化在 Flask 中 SQLAlchemy 的使用。SQLAlchemy 是目前python中最强大的 ORM框架, 功能全面, 使用简单。 ORM优缺点 优点 有语法提示, 省去自己拼写SQL&#xff0c;保证SQL…

spring的核心技术---bean的生命周期加案例分析详细易懂

目录 一.spring管理JavaBean的初始化过程&#xff08;生命周期&#xff09; Spring Bean的生命周期&#xff1a; 二.spring的JavaBean管理中单例模式及原型&#xff08;多例&#xff09;模式 2.1 . 默认为单例&#xff0c;但是可以配置多例 2.2.举例论证 2.2.1 默认单例 2.2…

前端常用算法(一):防抖+节流

目录 第一章 防抖 1.1 防抖&#xff08;debounce&#xff09;简介 1.2 应用场景 1.3 实现思路 1.4 手撕防抖代码 第二章 节流 2.1 节流&#xff08;throttle&#xff09;简介 2.2 应用场景 2.3 实现思路 2.4 手撕节流代码&#xff08;方法&#xff1a;时间戳和计时器…

MR300C工业无线WiFi图传模块 内窥镜机器人图像传输有线无线的两种方式

MR300C无线WiFi图传模使用方法工业机器人图像高清传输 ⚫ MR300C图传模块基于MIPS处理器实现&#xff0c;电脑/手机连接模块的WIFI热点或网口即可查看视频流 ⚫ 模块的USB 2.0 Host接口&#xff0c;可接入USB uvc摄像头/内窥镜默认输出的视频格式必须是MJPG ⚫ 模块支持接入摄…

计算机竞赛 图像识别-人脸识别与疲劳检测 - python opencv

文章目录 0 前言1 课题背景2 Dlib人脸识别2.1 简介2.2 Dlib优点2.3 相关代码2.4 人脸数据库2.5 人脸录入加识别效果 3 疲劳检测算法3.1 眼睛检测算法3.3 点头检测算法 4 PyQt54.1 简介4.2相关界面代码 5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是…

MongoDB升级经历(4.0.23至5.0.19)

MongoDB从4.0.23至5.0.19升级经历 引子&#xff1a;为了解决MongoDB的两个漏洞决定把MongoDB升级至最新版本&#xff0c;期间也踩了不少坑&#xff0c;在这里分享出来供大家学习与避坑~ 1、MongoDB的两个漏洞 漏洞1&#xff1a;MongoDB Server 安全漏洞(CVE-2021-20330) 漏洞2…

SpringBoot + Vue 微人事(十二)

职位批量删除实现 编写后端接口 PositionController DeleteMapping("/")public RespBean deletePositionByIds(Integer[] ids){if(positionsService.deletePositionsByIds(ids)ids.length){return RespBean.ok("删除成功");}return RespBean.err("删…

工业视觉相机镜头选型方法

一、相机选型 1、首先&#xff0c;根据检测需求确定选用黑白/彩色、面阵/线阵相机&#xff0c;接口类型一般选择GigE 2、确定检测精度要求&#xff08;最小特征尺寸mm&#xff09;、视野范围&#xff0c;一个测量精度对应几个像素数&#xff08;一般取3-5&#xff09; 3、计…

esp32c3 micropython oled实时天气信息

目录 简介 效果展示 代码 main.py ssd1306.py font.py 实现思路 简介 合宙esp32c3 micropython框架&#xff0c;只支持128*64 I2C oled ssd1306驱动我优化过的&#xff0c;与其他的不一样&#xff0c;为避免出错&#xff0c;使用我的驱动 把下面两个py文件放入单片机内…