【Vue框架】基本的login登录

前言

最近事情比较多,只能抽时间看了,放几天就把之前弄的都忘了,现在只挑着核心的部分看。现在铺垫了这么久,终于可以看前端最基本的登录了😂。

1、views\login\index.vue

由于代码比较长,这里将vue和js代码分开展示。

1.1、login的vue代码

<template><div class="login-container"><!-- 使用`loginForm`作为表单的数据模型,`loginRules`作为表单字段的验证规则,`ref`属性为`loginForm`用于在代码中引用该表单组件,`class`属性添加了`login-form`样式类名,`auto-complete`设置为`on`表示浏览器会自动完成输入,`label-position`设置为`left`表示标签位于输入框左侧--><el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left"><!--标题--><div class="title-container"><h3 class="title">Login Form</h3></div><!--一个表单项组件,用于包裹一个字段。`prop`属性设置为"username",用于表单验证。--><el-form-item prop="username"><span class="svg-container"><svg-icon icon-class="user" /></span><!--一个Element UI的输入框组件`ref="username"`:给输入框组件添加一个引用,用于在代码中引用该输入框组件`v-model="loginForm.username"`:利用双向绑定,将输入框的值与`loginForm`对象中的`username`属性进行绑定`placeholder="输入框的占位文字Username"`:设置输入框的占位文字"`type="text"`:设置输入框的类型为文本输入`tabindex="1"`:设置输入框的tab索引为1,用于设置键盘焦点的顺序`auto-complete="on"`:设置浏览器自动完成输入--><el-inputref="username"v-model="loginForm.username"placeholder="输入框的占位文字Username"name="username"type="text"tabindex="1"auto-complete="on"/></el-form-item><!--一个Element UI的工具提示组件,用于显示大写锁定键(Caps lock)的状态提示信息--><el-tooltip v-model="capsTooltip" content="Caps lock is On" placement="right" manual><el-form-item prop="password"><span class="svg-container"><svg-icon icon-class="password" /></span><!--`@keyup.native="checkCapslock"`:当键盘按键弹起时触发`checkCapslock`方法,用于检查大写锁定键的状态`@blur="capsTooltip = false"`:当输入框失去焦点时,隐藏大写锁定键提示`@keyup.enter.native="handleLogin"`:当按下Enter键时触发`handleLogin`方法,完成登录操作--><el-input:key="passwordType"ref="password"v-model="loginForm.password":type="passwordType"placeholder="输入框的占位文字Password"name="password"tabindex="2"auto-complete="on"@keyup.native="checkCapslock"@blur="capsTooltip = false"@keyup.enter.native="handleLogin"/><span class="show-pwd" @click="showPwd"><svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" /></span></el-form-item></el-tooltip><!--`@click`是Vue的事件绑定语法,`.native`修饰符用于监听组件根元素的原生(非自定义)事件。`.prevent`修饰符用于阻止事件的默认行为,例如阻止表单的提交行为--><el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button><div style="position:relative"><div class="tips"><span>Username : admin</span><span>Password : any</span></div><div class="tips"><span style="margin-right:18px;">Username : editor</span><span>Password : any</span></div><el-button class="thirdparty-button" type="primary" @click="showDialog=true">Or connect with</el-button></div></el-form><el-dialog title="Or connect with" :visible.sync="showDialog">Can not be simulated on local, so please combine you own business simulation! ! !<br><br><br><social-sign /></el-dialog></div>
</template>

1.2、login的js代码

<script>
import { validUsername } from '@/utils/validate'
import SocialSign from './components/SocialSignin'export default {name: 'Login',// 这个引入`SocialSign`中export default中所有的东西;SocialSign是第三方登录的内容components: { SocialSign },data() {// callback:函数变量,传入函数名称,可以复用,动态传入不同的函数使用// 定义验证方式const validateUsername = (rule, value, callback) => {// 验证用户名是否符合规则if (!validUsername(value)) {callback(new Error('Please enter the correct user name'))} else {callback()}}const validatePassword = (rule, value, callback) => {if (value.length < 6) {callback(new Error('The password can not be less than 6 digits'))} else {callback()}}// 一般变量的定义,都是在data()下的return中写return {// 用来记录前端交互的用户名和密码loginForm: {username: 'admin',password: '111111'},loginRules: {username: [{ required: true, trigger: 'blur', validator: validateUsername }],password: [{ required: true, trigger: 'blur', validator: validatePassword }]},passwordType: 'password',capsTooltip: false,loading: false,showDialog: false,redirect: undefined,otherQuery: {}}},watch: {$route: {handler: function(route) {const query = route.queryif (query) {this.redirect = query.redirectthis.otherQuery = this.getOtherQuery(query)}},immediate: true}},created() {// window.addEventListener('storage', this.afterQRScan)},// `mounted()`,在组件挂载后被调用mounted() {// `this.$refs`来访问已经挂载的`username`输入框组件,并调用其`focus()`方法来设置该输入框组件获取焦点if (this.loginForm.username === '') {this.$refs.username.focus()} else if (this.loginForm.password === '') {this.$refs.password.focus()}},destroyed() {// window.removeEventListener('storage', this.afterQRScan)},methods: {// 检查大写锁定键的方法checkCapslock({ shiftKey, key } = {}) {if (key && key.length === 1) {if (shiftKey && (key >= 'a' && key <= 'z') || !shiftKey && (key >= 'A' && key <= 'Z')) {this.capsTooltip = true} else {this.capsTooltip = false}}if (key === 'CapsLock' && this.capsTooltip === true) {this.capsTooltip = false}},// 是否显示具体密码showPwd() {if (this.passwordType === 'password') {this.passwordType = ''} else {this.passwordType = 'password'}this.$nextTick(() => {this.$refs.password.focus()})},// 实际登录的方法handleLogin() {// `validate`是`this.$refs.loginForm`访问到的登录表单组件的方法,// 这个方法会根据组件的表单验证规则进行验证,并将验证结果以参数的形式传递给回调函数this.$refs.loginForm.validate(valid => {if (valid) {this.loading = true// 访问store/modules/user.js中action下的方法loginthis.$store.dispatch('user/login', this.loginForm).then(() => {// `this.$router`全局路由,通过`push({path:'路径',query:{id:参数}})`进行路由跳转this.$router.push({ path: this.redirect || '/', query: this.otherQuery })this.loading = false}).catch(() => {this.loading = false})} else {console.log('error submit!!')return false}})},getOtherQuery(query) {return Object.keys(query).reduce((acc, cur) => {if (cur !== 'redirect') {acc[cur] = query[cur]}return acc}, {})}// afterQRScan() {//   if (e.key === 'x-admin-oauth-code') {//     const code = getQueryObject(e.newValue)//     const codeMap = {//       wechat: 'code',//       tencent: 'code'//     }//     const type = codeMap[this.auth_type]//     const codeName = code[type]//     if (codeName) {//       this.$store.dispatch('LoginByThirdparty', codeName).then(() => {//         this.$router.push({ path: this.redirect || '/' })//       })//     } else {//       alert('第三方登录失败')//     }//   }// }}
}
</script>

上面的内容涉及到callbackthis.$router的内容,具体可以参考以下链接了解:

  1. callback的使用
  2. vue this.$router.push 实现路由跳转

2、前端登录的执行流程图

根据views\login\index.vue的代码和【Vue框架】用户和请求的内容,整理得到他们的执行流程图,如下:
在这里插入图片描述
PS:前后端response内容关系不清楚的,可以看【Vue框架】用户和请求中的第5节。

3、src\permission.js

3.1 代码

import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar 用于显示进度条,NProgress显示页面加载或异步操作进度的JavaScript库
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title' // 用于获取页面标题// showSpinner: false不会显示旋转的加载图标,只会显示进度的条形动画
NProgress.configure({ showSpinner: false }) // NProgress Configuration// 定义了一些不需要进行路由重定向的白名单路径,例如`/login`和`/auth-redirect`。这些路径将被认为是无需进行重定向或权限检查的安全路径
const whiteList = ['/login', '/auth-redirect'] // no redirect whitelist/*** 在 Vue Router 中,全局前置守卫(Global before Guards)是一种用于拦截导航的机制,* 允许在路由切换之前对导航进行一些操作,比如进行身份验证、权限检查等。* 全局前置守卫是在 Vue Router 实例中注册的一组函数(constantRoutes和asyncRoutes),会在每次导航发生之前按照顺序执行。* 过调用 `router.beforeEach` 方法来注册全局前置守卫* 1. `to`:即将进入的路由。* 2. `from`:当前导航正要离开的路由。* 3. `next`:一个函数,用于控制导航的行为。需要在回调函数最后调用 `next` 方法来确认导航是否继续。*/
router.beforeEach(async(to, from, next) => {// start progress barNProgress.start()// set page titledocument.title = getPageTitle(to.meta.title)// determine whether the user has logged inconst hasToken = getToken()if (hasToken) {if (to.path === '/login') {// if is logged in, redirect to the home page 如果用户已经登录并且正在访问登录页面// 【用户从新打开页面,应该默认访问首页,然后这里来判断用户是否登录,如果登录就可以直接访问首页】// 重定向到主页next({ path: '/' })// 结束进度条NProgress.done()} else {// 如果用户已经登录,但不是在访问登录页面// determine whether the user has obtained his permission roles through getInfoconst hasRoles = store.getters.roles && store.getters.roles.length > 0if (hasRoles) {// 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。next()} else {try {// get user info// note: roles must be a object array! such as: ['admin'] or ,['developer','editor']// store是Vuex的实例,dispatch访问到里面action定义的方法('user/getInfo')const { roles } = await store.dispatch('user/getInfo')// generate accessible routes map based on rolesconst accessRoutes = await store.dispatch('permission/generateRoutes', roles)// dynamically add accessible routes// `addRoutes`方法只能在实例化Vue Router之后才能调用,且只能调用一次。否则会导致路由异常router.addRoutes(accessRoutes)// hack method to ensure that addRoutes is complete// set the replace: true, so the navigation will not leave a history recordnext({ ...to, replace: true })} catch (error) {// remove token and go to login page to re-loginawait store.dispatch('user/resetToken')Message.error(error || 'Has Error')next(`/login?redirect=${to.path}`) // 重定向到登录页面,并附带返回地址NProgress.done()}}}} else {/* has no token*/if (whiteList.indexOf(to.path) !== -1) {// in the free login whitelist, go directlynext()} else {// other pages that do not have permission to access are redirected to the login page.next(`/login?redirect=${to.path}`)NProgress.done()}}
})router.afterEach(() => {// finish progress barNProgress.done()
})

3.2 什么是路由守卫(导航守卫)

  • 个人理解:
    作用:从一个Vue文件(路由)跳转到另一个Vue文件(另一个路由),就会通过路由守卫来判断是否有权限正常跳转。

在这里插入图片描述
补充:
this.$router全局路由,通过push({path:'路径',query:{id:参数}})进行路由跳转,如下代码:

 this.$router.push({ path: this.redirect || '/', query: this.otherQuery })

个人理解:
push这里应该像是把route(路由)进栈,然后再根据路由守卫的next()指向要跳转的路由。

在这里插入图片描述
PS:理解能力有限,我画的这个是非常浅显的理解,如果大佬们想深入理解可以看下官方文档Vue Router
在这里插入图片描述

  • route是什么?
    在这里插入图片描述

3.3 代码中的主要逻辑

在3.2中提到,路由守卫是用来判断是否有权限正常跳转的,admin代码给出的判断逻辑如下图:
在这里插入图片描述
PS:一般好像也就是这样的逻辑

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

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

相关文章

一个简单的web应用程序的创建

一个简单的web应用程序的创建 1、数据库设计与创建1.1、数据库系统1.2、Navicat Premium1.3、Power Designer 2、使用maven创建SpringBoot项目2.1、配置maven2.2、安装idea2.3、使用idea创建maven项目2.4、根据需要配置pom.xml文件、配置项目启动相关的文件2.5、写SpringBoot项…

Unity——DOTween插件使用方法简介

缓动动画既是一种编程技术&#xff0c;也是一种动画的设计思路。从设计角度来看&#xff0c;可以有以下描述 事先设计很多基本的动画样式&#xff0c;如移动、缩放、旋转、变色和弹跳等。但这些动画都以抽象方式表示&#xff0c;一般封装为程序函数动画的参数可以在使用时指定&…

目标检测笔记(十一):如何结合特定区域进行目标检测(基于OpenCV的人脸检测实例)

文章目录 背景代码结果 背景 由于我们在做项目的时候可能会涉及到某个指定区域进行目标检测或者人脸识别等任务&#xff0c;所以这篇博客是为了探究如何在传统目标检测的基础上来结合特定区域进行检测&#xff0c;以OpenCV自带的包为例。 一般来说有两种方式实现区域指定&…

【动手学深度学习】--20.目标检测和边界框

文章目录 目标检测和边界框1.目标检测2.边界框 目标检测和边界框 学习视频&#xff1a;物体检测和数据集【动手学深度学习v2】 官方笔记&#xff1a;目标检测和边界框 在图像分类任务中&#xff0c;我们假设图像中只有一个主要物体对象&#xff0c;我们只关注如何识别其类别…

docker在阿里云上的镜像仓库管理

目录 一.登录进入阿里云网站&#xff0c;点击个人实例进行创建 二.创建仓库&#xff0c;填写相关信息 三.在访问凭证中设置固定密码用于登录&#xff0c;登录时用户名是使用你注册阿里云的账号名称&#xff0c;密码使用设置的固定密码 四.为镜像打标签并推送到仓库 五.拉取…

互联网医院成品功能你有哪些看法?

随着信息化的飞速发展&#xff0c;医疗领域信息化程度日益加深&#xff0c;医院对于信息化的自身需求越来越高&#xff0c;由此也推动了医院信息化的快速发展。而即时医疗信息服务能够解决普通老百姓医疗信息匮乏、花大钱看小病、就医不及时等基本问题。通过智能手机、平板电脑…

jdk 04 stream的collect方法

01.收集(collect) collect&#xff0c;收集&#xff0c;可以说是内容最繁多、功能最丰富的部分了。 从字面上去理解&#xff0c;就是把一个流收集起来&#xff0c;最终可以是收集成一个值也可以收集成一个新的集合。 collect主要依赖java.util.stream.Collectors类内置的静态方…

七大出海赛道解读,亚马逊云科技为行业客户量身打造解决方案

伴随全球化带来的新机遇和国内市场的进一步趋于饱和&#xff0c;近几年&#xff0c;中国企业出海快速升温&#xff0c;成为了新的创业风口和企业的第二增长曲线。从范围上看&#xff0c;出海市场由近及远&#xff0c;逐步扩张。从传统的东南亚市场&#xff0c;到成熟的北美、欧…

丰田中国vs中国丰田:一次历史性的战略探讨

比亚迪、长城、奇瑞等中国汽车品牌表现优异&#xff0c;让原本处于领先地位的日系、美系、德系等合资品牌面临压力&#xff0c;市场份额遭受前所未有的全新挑战。 东风雷诺、广汽菲克、广汽讴歌等逐渐退出中国市场&#xff0c;丰田也面临销售下滑。在中国汽车市场全新竞争格局下…

Qt跨平台无边框窗口探索记录

一、前言 实现的效果为&#xff1a;通过黑色矩形框预操作&#xff0c;鼠标释放时更新窗口。效果图如下&#xff1a; 1.功能 1.1 已实现功能 8个方向的缩放标题栏拖动标题栏双击最大化/正常窗口窗口最小尺寸预操作框颜色与背景色互补多屏幕默认标题栏 1.2 待开发功能 拖动到…

SQL-Injection

文章目录 引入columns表tables表schemata表以sqli-labs靶场为例路径获取常见方法文件读取函数文件写入函数防注入 数字型注入(post)字符型注入(get)搜索型注入xx型注入 引入 在MYSQL5.0以上版本中&#xff0c;mysql存在一个自带数据库名为information_schema,它是一个存储记录…

YOLOV1

YOU ONLY LOOK ONCE

学习ts(六)数据类型(元组、枚举、Symbol、never)与类型推论

1.元组 元组&#xff08;Tuple&#xff09;是固定数量的不同类型的元素的组合。是数组的变种。 元组与集合的不同之处在于&#xff0c;元组中的元素类型可以是不同的&#xff0c;而且数量固定。元组的好处在于可以把多个元素作为一个单元传递。如果一个方法需要返回多个值&…

生成式人工智能的潜在有害影响与未来之路(三)

产品责任法的潜在适用 背景和风险 产品责任是整个二十世纪发展起来的一个法律领域&#xff0c;旨在应对大规模生产的产品可能对社会造成的伤害。这一法律领域侧重于三个主要危害&#xff1a;设计缺陷的产品、制造缺陷的产品和营销缺陷的产品。产品责任法的特点有两个要素&…

R包开发1:RStudio 与 GitHub建立连接

目录 1.安装Git 2-配置Git&#xff08;只需配置一次&#xff09; 3-用SSH连接GitHub(只需配置一次) 4-创建Github远程仓库 5-克隆仓库到本地 目标&#xff1a;创建的R包&#xff0c;包含Git版本控制&#xff0c;并且能在远程Github仓库同步&#xff0c;相当于发布在Github。…

C语言练习2(巩固提升)

C语言练习2 选择题 前言 “志之所趋&#xff0c;无远弗届&#xff0c;穷山距海&#xff0c;不能限也。”对想做爱做的事要敢试敢为&#xff0c;努力从无到有、从小到大&#xff0c;把理想变为现实。要敢于做先锋&#xff0c;而不做过客、当看客&#xff0c;让创新成为青春远航的…

图为科技-边缘计算在智慧医疗领域的作用

边缘计算在智慧医疗领域的作用 随着科技的进步&#xff0c;智慧医疗已成为医疗行业的重要发展趋势。边缘计算作为新兴技术&#xff0c;在智慧医疗领域发挥着越来越重要的作用。本文将介绍边缘计算在智慧医疗领域的应用及其优势&#xff0c;并探讨未来发展方向。 一、边缘计算…

matlab使用教程(19)—曲线拟合与一元方程求根

1.多项式曲线拟合 此示例说明如何使用 polyfit 函数将多项式曲线与一组数据点拟合。您可以按照以下语法&#xff0c;使用 polyfit 求出以最小二乘方式与一组数据拟合的多项式的系数 p polyfit(x,y,n), 其中&#xff1a; • x 和 y 是包含数据点的 x 和 y 坐标的向量 …

uniapp 安卓平台签名证书(.keystore)生成

安装JRE环境 下载jre安装包&#xff1a;https://www.oracle.com/java/technologies/downloads/#java8安装jre安装包时&#xff0c;记录安装目录(例:C:\Program Files\Java\jdk-20)打开命令行&#xff08;cmd&#xff09;&#xff0c;将JRE安装路径添加到系统环境变量 d: se…

PostgreSQL基本操作总结

安装按PostgreSQL数据库后&#xff0c;会默认创建用户postgres和数据库postgres&#xff0c;这个用户是超级用户&#xff0c;权限最高&#xff0c;可以创建其他用户和权限&#xff0c;在实际开发过程中&#xff0c;会新创建用户和业务数据库&#xff0c;本文主要介绍用户权限和…