【Vue3从入门到项目实现】RuoYi-Vue3若依框架前端学习——登录页面

若依官方的前后端分离版中,前端用的Vue2,这个有人改了Vue3的前端出来。刚好用来学习:
https://gitee.com/weifengze/RuoYi-Vue3

运行前后端项目

首先运行项目
启动前端,npm installnpm run dev
启动后端,按教程配置数据库、redis环境,启动即可

在这里插入图片描述

页面实现文件在:RUOYI-VUE3/src/views/login.vue

验证码

function getCode() {getCodeImg().then(res => {captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled;if (captchaEnabled.value) {codeUrl.value = "data:image/gif;base64," + res.img; //后端传来的验证码图片地址loginForm.value.uuid = res.uuid;}});
}
//页面初始化, 获取验证码
getCode();

getCodeImg()方法封装在 RUOYI-VUE3/src/api/login.js

// 获取验证码
export function getCodeImg() {return request({url: '/captchaImage',headers: {isToken: false},method: 'get',timeout: 20000})
}

前端Vue和后端Springboot交互时通常使用axios(ajax)。
发现getCodeImg()方法内还有一个 request()的封装在:RUOYI-VUE3/src/utils/request.js

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({// axios中请求配置有baseURL选项,表示请求URL公共部分baseURL: import.meta.env.VITE_APP_BASE_API,// 超时timeout: 10000
})

这个VITE_APP_BASE_API 常量,根据不同的运行情况,在这些文件里面:
在这里插入图片描述
例如现在运行的是dev环境。就在.env.development
在这里插入图片描述

前端发生的请求url为:http://localhost/dev-api/captchaImage
就是request.js这里封装了一个baseURL, 然后getCodeImg()方法里写了/captchaImage接口地址。
在这里插入图片描述

反向代理

后端运行在localhost:8080端口上,前端运行在localhost:80端口上。
浏览器访问的是前端项目,如果要调用后端接口,会跨域。
跨域问题可以由后端解决:写一个允许跨域的配置类
跨域问题也可以由前端解决:反向代理。

反向代理的配置在:RUOYI-VUE3/vite.config.js中:

// vite 相关配置server: {port: 80,host: true,open: true,proxy: {// https://cn.vitejs.dev/config/#server-proxy'/dev-api': {target: 'http://localhost:8080',changeOrigin: true,rewrite: (p) => p.replace(/^\/dev-api/, '')}}},

代码解释:
'/dev-api' 是代理的前缀路径,表示所有以 ‘/dev-api’ 开头的请求都会被代理。
target: 'http://localhost:8080' 指定了代理的目标地址,即真实的后端服务地址。
changeOrigin: true 通常是设置为 true,以便确保请求头中的 Host 字段保持一致,防止一些反向代理的问题。
rewrite: (p) => p.replace(/^\/dev-api/, '') 用于重写请求路径,它将路径中的 ‘/dev-api’ 前缀去掉,以适应后端的实际路径。
这样配置之后,当你在前端代码中发起类似于 ‘/dev-api/captchaImage’ 的请求时,
Vite 将把这个请求代理到 ‘http://localhost:8080/captchaImage’。

登录

和验证码一样的流程,登录功能主要由handleLogin()方法实现
在这里插入图片描述
userStroreRUOYI-VUE3/src/store/module/user.js 是Vuex的用法

Vuex:

集中式状态管理: 当应用变得复杂时,组件之间共享状态可能变得困难。Vuex 提供了一个集中式的状态管理机制,使状态的变化可预测且容易调试。

全局访问: 通过 Vuex,可以在任何组件中访问相同的状态。这样,你就可以在组件之间共享数据,而不需要通过繁琐的组件通信来传递数据。

状态持久化: Vuex 允许你将状态持久化到本地存储,以便在页面刷新或重新加载时仍然保留应用的状态。

userStrore

const useUserStore = defineStore('user',{state: () => ({token: getToken(),name: '',avatar: '',roles: [],permissions: []}),actions: {login(userInfo) {// ...},getInfo() {// ...},logOut() {// ...}}}
)
export default useUserStore

defineStore 是 Vuex 4 中新引入的函数,用于创建 store 模块。
'user'是模块的名称。
state 中定义了用户模块的初始状态,包括 token、name、avatar、roles 和 permissions 等初始状态信息。
action中定义登录相关的 actions:
最后导出useUserStore,以便在应用的其他地方可以引入并使用这个 store 模块。

外层login(userInfo) 方法.
根据传入的用户信息构建并返回一个Promise,它是es6提供的异步处理的对象
里面的login(username, password, code, uuid) 和前面的getCodeImg()方法一样,在RUOYI-VUE3/src/api/login.js中,封装的一个request,最终还是ajax

	login(userInfo) {const username = userInfo.username.trim()const password = userInfo.passwordconst code = userInfo.codeconst uuid = userInfo.uuidreturn new Promise((resolve, reject) => {login(username, password, code, uuid).then(res => {setToken(res.token)this.token = res.tokenresolve()}).catch(error => {reject(error)})})},

登录成功后,后端返回的结果中有一个Token.

import Cookies from 'js-cookie'const TokenKey = 'Admin-Token'export function getToken() {return Cookies.get(TokenKey)
}export function setToken(token) {return Cookies.set(TokenKey, token)
}export function removeToken() {return Cookies.remove(TokenKey)
}

setToken(res.token) 就是把这个后端返回的Token放到Cookies中。

Vue Router

//使用 Vue Router 中的 useRouter 函数创建了一个 router 对象。
const router = useRouter()

常见用法就是:

// 字符串
router.push('home')
// 命名的路由
router.push({ name: 'user', params: { userId: 123 }})
//对象
router.push({ path: redirect.value || "/" });

router的 push方法和replace方法的详细用法:https://blog.csdn.net/sunhuaqiang1/article/details/85220888

点击登录后,后端业务会去验证:验证码、账号、密码。正确就登录成功。后端登录方法中还会调用recordLoginInfo()方法记录登录信息,写入日志。

获取用户角色和权限

通过浏览器的请求可以发现,登录成功后,还会调用getInfogetRouters

在这里插入图片描述
它们是在RUOYI-VUE3/src/permission.js中被调用的
beforeEachVue Router 提供的全局前置守卫函数,前端每个页面进行跳转前都会执行这个函数。

router.beforeEach((to, from, next) => {NProgress.start()if (getToken()) {to.meta.title && useSettingsStore().setTitle(to.meta.title)/* 如果即将进入的路由是 /login,则直接重定向到根路径 /,表示已经登录的情况下不允许再访问登录页面。*/if (to.path === '/login') {next({ path: '/' })NProgress.done()} else {//如果角色信息未获取,则去请求user_info和路由表if (useUserStore().roles.length === 0) {isRelogin.show = true// 判断当前用户是否已拉取完user_info信息useUserStore().getInfo().then(() => {isRelogin.show = falseusePermissionStore().generateRoutes().then(accessRoutes => {// 根据roles权限生成可访问的路由表accessRoutes.forEach(route => {if (!isHttp(route.path)) {router.addRoute(route) // 动态添加可访问路由表}})next({ ...to, replace: true }) // hack方法 确保addRoutes已完成})}).catch(err => {useUserStore().logOut().then(() => {ElMessage.error(err)next({ path: '/' })})})} else {next()}}} else {// 没有tokenif (whiteList.indexOf(to.path) !== -1) {// 在免登录白名单,直接进入next()} else {next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页NProgress.done()}}
})router.afterEach(() => {NProgress.done()
})

具体的动态路由和角色权限管理,且听下回分解

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

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

相关文章

自定义登录页面模板(移动端)

login/index <script setup lang"ts"> </script><template><div class"login-page">//组件 由于配置了自动注册&#xff0c;所以无需引入<cp-nav-barright-text"注册"click-right"$router.push(/register)&quo…

Codeforces Round 913 (Div. 3)补题

Rook 题目大意&#xff1a;我们给定一个棋盘(如下图)&#xff0c;棋盘上有一个车&#xff0c;问车可以到的位置&#xff0c;任意顺序输出即可。 思路&#xff1a;输出车的行列中非它本身的点即可。 #include<bits/stdc.h> using namespace std; int main() {int t;scanf…

Fabric:链码的部署及执行

Hyperledger Fabric:V2.5.4 写在最前 使用Fabric搭建自定义网络参考&#xff1a;https://blog.csdn.net/yeshang_lady/article/details/134113296 使用Fabric创建应用通道参考&#xff1a;https://blog.csdn.net/yeshang_lady/article/details/134668458 接下来将介绍如何在自…

ELK的日志解决方案

1. 安装和配置ELK 确保你已经安装了Elasticsearch、Logstash和Kibana。你可以按照官方文档或使用包管理工具进行安装。 Elasticsearch官方配置文档 Kibana官方配置文档 2. Logstash配置 拉取logstash 创建容器 docker run -it \ --name logstash \ --privileged \ -p 5044:5…

Ubuntu-Sim2Real环境配置(下)

cd ICRA-RM-Sim2Real/docker_client/ ./exec_client.sh cd ~ roslaunch rtab_navigation rtab_navigation.launch 执行上面代码的时候后台一直刷新 cd ICRA-RM-Sim2Real/docker_client/ ./exec_client.sh cd ~ roslaunch carto_navigation navigation.launch 1.Usage 执行该…

【微服务】spring循环依赖深度解析

目录 一、循环依赖概述 1.2 spring中的循环依赖 二、循环依赖问题模拟 2.1 循环依赖代码演示 2.2 问题分析与解决 2.2.1 使用反射中间容器 三、spring循环依赖问题解析 3.1 spring中的依赖注入 3.1.1 field属性注入 3.1.2 setter方法注入 3.1.3 构造器注入 3.2 spri…

树莓派学习:wiringPi+硬件pwm+舵机

目录 目的 代码 只有io口1是支持pwm&#xff0c;其他要软件pwm 编译 运行 目的 黄色pwm&#xff0c;红色正极&#xff0c;棕色负极 让sg90舵机转动&#xff0c;就需要一个20ms的周期pwm&#xff0c;其中高电平在0.5-2.5ms之间 转动角度 高电平在一个周期内的时间0 …

ElasticSearch篇---第四篇

系列文章目录 文章目录 系列文章目录前言一、elasticsearch 是如何实现 master 选举的?二、elasticsearch 索引数据多了怎么办,如何调优,部署?三、说说你们公司 es 的集群架构,索引数据大小,分片有多少?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽…

集成开发环境 PyCharm 的安装【侯小啾python基础领航计划 系列(二)】

集成开发环境PyCharm的安装【侯小啾python基础领航计划 系列(二)】 大家好,我是博主侯小啾, 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔…

LeetCode Hot100 207.课程表

题目&#xff1a; 你这个学期必须选修 numCourses 门课程&#xff0c;记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出&#xff0c;其中 prerequisites[i] [ai, bi] &#xff0c;表示如果要学习课程 ai 则 必须 先学习…

掌握大型语言模型(LLM)技术:推理优化

原文链接&#xff1a;Mastering LLM Techniques: Inference Optimization | NVIDIA Technical Blog 大模型相关技术文章已整理到Github仓库&#xff0c;欢迎start! 堆叠Transformer层以创建大型模型可以获得更好的准确性、few-shot学习能力&#xff0c;甚至在各种语言任务中具有…

Kafka 的特点和优势

Apache Kafka 作为一款分布式流处理平台&#xff0c;以其独特的特点和卓越的优势成为实时数据处理领域的瑰宝。本文将深入研究 Kafka 的各项特点和优势&#xff0c;并通过详实的示例代码展示其在不同场景下的强大应用。 高吞吐量和水平扩展 Kafka 的设计注重高吞吐量和水平扩…

Python-炸弹人【附完整源码】

炸弹人 炸弹人是童年的一款经典电子游戏&#xff0c;玩家控制一个类似"炸弹人"的角色&#xff0c;这个角色可以放置炸弹&#xff0c;并在指定的时间内引爆它们消灭敌人以达到目标&#xff0c;此游戏共设有两节关卡&#xff0c;代码如下&#xff1a; 运行效果&#x…

python将时间戳转换为时间

python将时间戳转换为时间 import datetime timestamp 1701862813779 # 将时间戳转换为秒&#xff08;因为Python的timestamp通常是以秒为单位的&#xff09; timestamp_seconds timestamp / 1000 # 将时间戳转换为UTC时间 utc_time datetime.datetime.utcfromti…

空间金字塔池化(SPP,Spatial Pyramid Pooling)系列

空间金字塔池化的作用是解决输入图片大小不一造成的缺陷&#xff0c;同时在目标识别中增加了精度。空间金字塔池化可以使得任意大小的特征图都能够转换成固定大小的特征向量&#xff0c;下面针对一些典型的空间金字塔进行盘点。 部分图片来自blog:空间金字塔池化改进 SPP / SP…

每天一点python——day88

#每天一点Python——88 #编程两大思想【面向过程与面向对象】 #如图&#xff1a; 面向过程的线性思维&#xff1a; 类似于做菜一步步的来&#xff0c;先怎么样怎么样&#xff0c;再怎么样 如果不一步步的来&#xff0c;例如先炒菜再点火&#xff0c;这样是做不好的 面向对象&a…

IntelliJ IDE 插件开发 | (二)UI 界面与数据持久化

系列文章 IntelliJ IDE 插件开发 |&#xff08;一&#xff09;快速入门 前言 在上一篇文章中介绍了在IDEA下开发、运行和安装插件的基本步骤&#xff0c;因此创建项目等基础步骤不再赘述&#xff0c;本文则开始介绍如何进行 UI 界面的开发以及相关数据的持久化存储&#xff…

安全测试工具,自动发现网站所有URL!

作为一个安全测试人员来说&#xff0c;首先要拿到网站所有url&#xff0c;然后根据拿到的url进行渗透测试进行漏洞挖掘。本文给大家介绍的是如何拿到一个网站所有的url。 深度爬取层级控制 现在我也找了很多测试的朋友&#xff0c;做了一个分享技术的交流群&#xff0c;共享了很…

ospf选路

问题描述 R6通过主备份路径访问LSP&#xff08;R1&#xff09;&#xff0c;主为R2&#xff0c; 备为R3 解决方案 路由器1看作LSP&#xff0c;配置loopback 0 ,地址为1.1.1.1 供测试使用&#xff1b;路由器 236, LSW4和LSW5&#xff0c; 运行ospf处于相同区域&#xff0c;建立…

Redis核心知识点总结

1.Redis介绍 Redis 是 NoSQL&#xff0c;但是可处理 1 秒 10w 的并发&#xff08;数据都在内存中&#xff09; 使用 java 对 redis 进行操作类似 jdbc 接口标准对 mysql&#xff0c;有各类实现他的实现类&#xff0c;我们常用的是 druid 其中对 redis&#xff0c;我们通常用 J…