当前位置: 首页 > news >正文

【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:一般好像也就是这样的逻辑

相关文章:

【Vue框架】基本的login登录

前言 最近事情比较多&#xff0c;只能抽时间看了&#xff0c;放几天就把之前弄的都忘了&#xff0c;现在只挑着核心的部分看。现在铺垫了这么久&#xff0c;终于可以看前端最基本的登录了&#x1f602;。 1、views\login\index.vue 由于代码比较长&#xff0c;这里将vue和js…...

Python21天打卡Day16-内置方法map()

在 Python 中&#xff0c;map() 方法是一个内置的函数&#xff0c;用于将函数应用于可迭代对象&#xff08;如列表、元组等&#xff09;中的每个元素&#xff0c;返回一个包含结果的迭代器。 map() 方法的语法如下&#xff1a; map(function, iterable)function&#xff1a;表…...

伦敦银和伦敦金的区别

伦敦银河伦敦金并称贵金属交易市场的双璧&#xff0c;一般投资贵金属的投资者其实不是交易伦敦金就是交易伦敦银。相信经过一段时间的学习和投资&#xff0c;不少投资者都能分辨二者的区别。下面我们就来谈谈伦敦银和伦敦金有什么异同&#xff0c;他们在投资上是否有差别。 交易…...

【从零学习python 】92.使用Python的requests库发送HTTP请求和处理响应

文章目录 URL参数传递方式一&#xff1a;使用字典传递参数URL参数传递方式二&#xff1a;直接在URL中拼接参数获取响应头信息获取响应体数据a. 获取二进制数据b. 获取字符数据c. 获取JSON数据 进阶案例 URL参数传递方式一&#xff1a;使用字典传递参数 url https://www.apiop…...

Python requests实现图片上传接口自动化测试

最近帮别人写个小需求&#xff0c;需要本地自动化截图&#xff0c;然后图片自动化上传到又拍云&#xff0c;实现自动截图非常简单&#xff0c;在这里就不详细介绍了&#xff0c;主要和大家写下&#xff0c;如何通过Pythonrequests实现上传本地图片到又拍云服务器。 话不多说&a…...

【LeetCode-面试经典150题-day13】

目录 141.环形链表 2.两数相加 21.合并两个有序链表 138.复制带随机指针的链表 92.反转链表Ⅱ 141.环形链表 题意&#xff1a; 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;…...

taro.js和nutui实现商品选择页面

1. 首先安装 Taro.js 和 NutUI: npm install -g tarojs/cli npm install taro-ui 2. 创建 Taro 项目并进入项目目录&#xff1a; taro init myapp cd myapp 3. 选用 Taro 模板一并安装依赖&#xff1a; npm install 4. 在页面目录中创建商品选择页&#xff1a; taro cre…...

数据结构--算法的时间复杂度和空间复杂度

文章目录 算法效率时间复杂度时间复杂度的概念大O的渐进表示法计算实例 时间复杂度实例 常见复杂度对比例题 算法效率 算法效率是指算法在计算机上运行时所消耗的时间和资源。这是衡量算法执行速度和资源利用情况的重要指标。 例子&#xff1a; long long Fib(int N) {if(N …...

Vue中使用element-plus中的el-dialog定义弹窗-内部样式修改-v-model实现-demo

效果图 实现代码 <template><el-dialog class"no-code-dialog" v-model"isShow" title"没有收到验证码&#xff1f;"><div class"nocode-body"><div class"tips">请尝试一下操作</div><d…...

MySQL 主从配置

环境 centos6.7 虚拟机两台 主&#xff1a;192.168.23.160 从&#xff1a;192.168.23.163 准备 在两台机器上分别安装mysql5.6.23&#xff0c;安装完成后利用临时密码登录mysql数据修改root的密码&#xff1b;将my.cnf配置文件放至/etc/my.cnf&#xff0c;重启mysql服务进…...

上海亚商投顾:创业板指反弹大涨1.26% 核污染概念股午后全线走强

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪 三大指数今日集体反弹&#xff0c;沪指午后冲高回落&#xff0c;创业板指盘中涨超2%&#xff0c;尾盘涨幅也有所收…...

Mysql数据库管理

一、数据库基本概念 数据 使用一些介质进行存储&#xff0c;例如文字存在文档中 数据库可以完成数据持久化保存快速提取 那么想要实现以上功能&#xff0c;需要编写一系列的规则--》SQL语句 SQL语句 按功能分类: 增删改查 数据库类型&#xff1a;关系型数据库、非关系型数据库…...

【java安全】FastJson反序列化漏洞浅析

文章目录 【java安全】FastJson反序列化漏洞浅析0x00.前言0x01.FastJson概述0x02.FastJson使用序列化与反序列化 0x03.反序列化漏洞0x04.漏洞触发条件0x05.漏洞攻击方式JdbcRowSetImpl利用链TemplatesImpl利用链**漏洞版本**POC漏洞分析 【java安全】FastJson反序列化漏洞浅析 …...

pytestx重新定义接口框架设计

概览 脚手架&#xff1a; 目录&#xff1a; 用例代码&#xff1a; """ 测试登录到下单流程&#xff0c;需要先启动后端服务 """test_data {"查询SKU": {"skuName": "电子书"},"添加购物车": {"sk…...

【文生图系列】Stable Diffusion原理篇

文章目录 Stable Diffusion的组成什么是扩散扩散是如何工作的去噪声绘制图像将文本信息添加到图像生成器中参考 “文生图”&#xff0c;或者AI绘画&#xff0c;最近异常火爆&#xff0c;输入一些描述性的语句&#xff0c;AI就能够生成相应的画作。甚至引发了一个问题&#xff1…...

ARM-汇编指令

一&#xff0c;map.lds文件 链接脚本文件 作用&#xff1a;给编译器进行使用&#xff0c;告诉编译器各个段&#xff0c;如何进行分布 /*输出格式&#xff1a;32位可执行程序&#xff0c;小端对齐*/ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm",…...

Java相关知识对应leetcode

力扣账号&#xff1a;华为邮箱 类知识点力扣链接Integer转为String Character 判断字符是否是字母或者数字转为小写字母 不可修改 String 转为字符串数组 是否包含某个字符或者字符位置 可修改 StringBuffer 单个字符获取 string转为StringBufferStringBuffer转为String字符…...

js中?.、??、??=的用法及使用场景

上面这个错误&#xff0c;相信前端开发工程师应该经常遇到吧&#xff0c;要么是自己考虑不全造成的&#xff0c;要么是后端开发人员丢失数据或者传输错误数据类型造成的。因此对数据访问时的非空判断就变成了一件很繁琐且重要的事情&#xff0c;下面就介绍ES6一些新的语法来方便…...

每日一题:leetcode 1109 航班预订统计

这里有 n 个航班&#xff0c;它们分别从 1 到 n 进行编号。 有一份航班预订表 bookings &#xff0c;表中第 i 条预订记录 bookings[i] [firsti, lasti, seatsi] 意味着在从 firsti 到 lasti &#xff08;包含 firsti 和 lasti &#xff09;的 每个航班 上预订了 seatsi 个座…...

C#__自定义类传输数据和前台线程和后台线程

// 前台线程和后台线程 // 默认情况下&#xff0c;用Thread类创建的线程是前台线程。线程池中的线程总是后台线程。 // 用Thread类创建线程的时候&#xff0c;可以设置IsBackground属性&#xff0c;表示一个后台线程。 // 前台线程在主函数运行结束后依旧执行&#xff0c;后台线…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机&#xff0c;它可以执行Java字节码。Java虚拟机是Java平台的一部分&#xff0c;Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

MySQL的pymysql操作

本章是MySQL的最后一章&#xff0c;MySQL到此完结&#xff0c;下一站Hadoop&#xff01;&#xff01;&#xff01; 这章很简单&#xff0c;完整代码在最后&#xff0c;详细讲解之前python课程里面也有&#xff0c;感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...

面试高频问题

文章目录 &#x1f680; 消息队列核心技术揭秘&#xff1a;从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"&#xff1f;性能背后的秘密1.1 顺序写入与零拷贝&#xff1a;性能的双引擎1.2 分区并行&#xff1a;数据的"八车道高速公路"1.3 页缓存与批量处理…...