黑马头条vue2.0项目实战(二)——登录注册功能的实现

1. 布局结构

目标

  • 能实现登录页面的布局

  • 能实现基本登录功能

  • 能掌握 Vant 中 Toast 提示组件的使用

  • 能理解 API 请求模块的封装

  • 能理解发送验证码的实现思路

  • 能理解 Vant Form 实现表单验证的使用

这里主要使用到三个 Vant 组件:

  • NavBar 导航栏

  • Form 表单

    • Field 输入框

    • Button 按钮

1.1 布局样式

        写样式的原则:将公共样式写到全局(src/styles/index.less),将局部样式写到组件内部。对于需要更改样式,自己添加 class 类名。

1.2 自定义图标的使用

官方文档实现:

实现效果:

最左侧显示的图标无法满足需求的情况下,可以通过 slot 实现,插入自定义的图标。可以插入的slot如下所示:

具体实现,通过插入 i 标签,设置 iconfont 类名。

1.2 插入按钮

官方文档:

实现效果:

        但是在表单中,除了提交按钮外,可能还有一些其他的功能性按钮,如发送验证码按钮。在使用这些按钮时,要注意将 native-type设置为button,否则会触发表单提交。

2. 实现基本登录功能

功能需求:

  • 注册点击登录的事件

  • 获取表单数据(根据接口要求使用 v-model 绑定)

  • 表单验证

  • 发请求提交

  • 根据请求结果做下一步处理

2.1 登录状态提示

2.2 表单验证

  •  给 vant-field 组件配置 rules 验证规则     

  • 可以在 data 里自定义校验规则校验手机号和验证码

  • 当给表单提交的时候会自动触发表单验证
    • 如果验证通过,则触发 submit 事件
    • 如果验证不通过,则不会触发 submit 事件
    • 验证规则 参考vant组件的文档

2.3 验证码处理

点击发送验证码功能

功能需求:

  • 点击发送验证码按钮后,对用户输入的手机号进行验证

  • 验证通过显示倒计时

  • 发送用户手机号给后端,后台给用户手机下发验证码
  • 发送失败关闭倒计时

注意:

  • 这里的 ref 是绑在表单 Form上
  • 获取表单实例之后,通过 .validate('校验表单或输入框的name属性值')
  • 返回的是一个 promise 对象

3. 处理用户 Token

Token 是用户登录成功之后服务端返回的一个身份令牌,在项目中的多个业务中需要使用到:

  • 访问需要授权的 API 接口

  • 校验页面的访问权限

  • ...

但是我们只有在第一次用户登录成功之后才能拿到 Token。

所以为了能在其它模块中获取到 Token 数据,我们需要把它存储到一个公共的位置,方便随时取用。

往哪儿存?

  • 本地存储

    • 获取麻烦

    • 数据不是响应式

  • Vuex 容器(推荐)

    • 获取方便

    • 响应式的

3.1 使用容器存储 Token 的思路

  • 登录成功,将 Token 存储到 Vuex 容器中

    • 获取方便

    • 响应式

  • 为了持久化,还需要把 Token 放到本地存储

    • 持久化

登录成功以后将后端返回的 token 相关数据存储到容器中

3.2 优化封装本地存储操作模块

创建 src/utils/storage.js 模块

3.3 关于 Token 过期问题

登录成功之后后端会返回两个 Token:

  • token:访问令牌,有效期2小时

  • refresh_token:刷新令牌,有效期14天,用于访问令牌过期之后重新获取新的访问令牌

我们的项目接口中设定的 Token 有效期是 2 小时,超过有效期服务端会返回 401 表示 Token 无效或过期了。

为什么过期时间这么短?

  • 为了安全,例如 Token 被别人盗用

过期了怎么办?

  • 让用户重新登录,用户体验太差了

  • 使用 refresh_token 解决 token 过期

后续拓展 Token 过期处理 ,在学习测试的时候如果收到 401 响应码,请重新登录再测试

概述:服务器生成token的过程中,会有两个时间,一个是token失效时间,一个是token刷新时间,刷新时间肯定比失效时间长,当用户的 token 过期时,你可以拿着过期的token去换取新的token,来保持用户的登陆状态,当然你这个过期token的过期时间必须在刷新时间之内,如果超出了刷新时间,那么返回的依旧是 401。

处理流程:

  1. 在axios的拦截器中加入token刷新逻辑

  2. 当用户token过期时,去向服务器请求新的 token

  3. 把旧的token替换为新的token

  4. 然后继续用户当前的请求

在请求的响应拦截器中统一处理 token 过期(后续拓展)。

/*** 封装 axios 请求模块*/
import axios from "axios";
import jsonBig from "json-bigint";
import store from "@/store";
import router from "@/router";// axios.create 方法:复制一个 axios
const request = axios.create({baseURL: "http://ttapi.research.itcast.cn/" // 基础路径
});/*** 配置处理后端返回数据中超出 js 安全整数范围问题*/
request.defaults.transformResponse = [function(data) {try {return jsonBig.parse(data);} catch (err) {return {};}}
];// 请求拦截器
request.interceptors.request.use(function(config) {const user = store.state.user;if (user) {config.headers.Authorization = `Bearer ${user.token}`;}// Do something before request is sentreturn config;},function(error) {// Do something with request errorreturn Promise.reject(error);}
);// 响应拦截器
request.interceptors.response.use(// 响应成功进入第1个函数// 该函数的参数是响应对象function(response) {// Any status code that lie within the range of 2xx cause this function to trigger// Do something with response datareturn response;},// 响应失败进入第2个函数,该函数的参数是错误对象async function(error) {// Any status codes that falls outside the range of 2xx cause this function to trigger// Do something with response error// 如果响应码是 401 ,则请求获取新的 token// 响应拦截器中的 error 就是那个响应的错误对象console.dir(error);if (error.response && error.response.status === 401) {// 校验是否有 refresh_tokenconst user = store.state.user;if (!user || !user.refresh_token) {router.push("/login");// 代码不要往后执行了return;}// 如果有refresh_token,则请求获取新的 tokentry {const res = await axios({method: "PUT",url: "http://ttapi.research.itcast.cn/app/v1_0/authorizations",headers: {Authorization: `Bearer ${user.refresh_token}`}});// 如果获取成功,则把新的 token 更新到容器中console.log("刷新 token  成功", res);store.commit("setUser", {token: res.data.data.token, // 最新获取的可用 tokenrefresh_token: user.refresh_token // 还是原来的 refresh_token});// 把之前失败的用户请求继续发出去// config 是一个对象,其中包含本次失败请求相关的那些配置信息,例如 url、method 都有// return 把 request 的请求结果继续返回给发请求的具体位置return request(error.config);} catch (err) {// 如果获取失败,直接跳转 登录页console.log("请求刷新 token 失败", err);router.push("/login");}}return Promise.reject(error);}
);export default request;

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

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

相关文章

人工智能算法工程师(高级)课程7-图像分割项目之DeepLab模型的搭建与代码详解

大家好,我是微学AI,今天给大家介绍一下人工智能算法工程师(高级)课程7-图像分割项目之DeepLab模型的搭建与代码详解。本文将详细介绍DeepLab模型的关键组成部分,包括Image Pyramid、Encoder-Decoder、SPP模型和ASPP模型。我们将从数学原理出发,配合LaTeX公式,并使用PyTorc…

docker Docs相关使用文档链接

Docker Docshttps://docs.docker.com/ docker compose | Docker Docshttps://docs.docker.com/reference/cli/docker/compose/docker | Docker Docshttps://docs.docker.com/reference/cli/docker/

工作很难受,还要不要继续留在职场上?

先说结论:我非常赞同大家离开职场 虽然小编现实的工作是有关于人力资源的,高级点叫做猎头,低俗点讲就叫“人贩子” 原因可能和其他人不太一样,大家自行理解 1.现在的社会资源太少,“蛋糕”太小 大家要明白最重要的…

Ethernet

目录 1. Physical Layer(PHY)2. MAC2.1. MAC帧格式2.2. MAC地址与IP地址3. RGMII接口FPGA实现以太网(一)——以太网简介 以太网(Ethernet)是指遵守 IEEE 802.3 标准组成的局域网通信标准, IEEE 802.3 标准规定的主要是OSI参考模型中的物理层(PHY)和数据链路层中的介质访问控…

【HZHY-AI300G智能盒试用连载体验】设置RKNN的开发环境

目录 安装RKNN工具 安装pip3 安装RKNN Toolkit Lite2 安装RKNPU2运行库 本文首发于电子发烧友论坛:【新提醒】【HZHY-AI300G智能盒试用连载体验】 智能工业互联网网关 - 北京合众恒跃科技有限公司 - 电子技术论坛 - 广受欢迎的专业电子论坛! (elecfans.com) 前…

go语言day20 使用gin框架获取参数 使用自定义的logger记录日志

Golang 操作 Logger、Zap Logger 日志_golang zap-CSDN博客 一、 从控制器中获取参数的几种形式 1) 页面请求url直接拼接参数。 2) 页面请求提交form表单 3) 页面请求发送json数据,使用上下文对象c的BindJSON()方法接收数据…

CI/CD:Job failed: execution took longer than 1h0m0s seconds

简介:当在CI/CD配置运行Gitlab-runner流水线中,一般默认情况下,Job的执行时间默认为1小时,如果超出1小时,任务会中断。 历史攻略: 定时任务:Jenkins 容器化CICDLocust性能压测 容器化CICDSo…

【C++ —— 认识哈希和unordered_set、unordered_map的介绍及模拟】

认识哈希和unordered_set、unordered_map的介绍及模拟 哈希表基础哈希的概念哈希表的基本操作 哈希冲突哈希冲突的定义哈希冲突的影响常见的哈希冲突的解决方法 哈希函数哈希函数的定义哈希函数的设计原则常见的哈希函数 unordered系列关联式容器hash模拟 哈希表基础 哈希的概…

AI大模型大厂面试真题:「2024大厂大模型技术岗内部面试题+答案」

AI大模型岗的大厂门槛又降低了!实在太缺人了,大模型岗位真的强烈建议各位多投提前批,▶️众所周知,2025届秋招提前批已经打响,🙋在这里真心建议大家6月7月一定要多投提前批! 💻我们…

树莓派_Opencv学习笔记23:模版样本匹配

今日继续学习树莓派4B 4G:(Raspberry Pi,简称RPi或RasPi) 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: ​ Opencv 版本是4.5.1: ​ Python 版本3.7.3: 今日学习Opencv样本…

【日常记录】【插件】Typed.js:用于创建打字效果的 JavaScript 库

文章目录 1. 引言2. 安装3. 基本使用参考链接 1. 引言 Typed.js是一个用于创建打字效果的 JavaScript 库。这个效果就是 chatgpt、百度的文心一言等其他的大模型,回复用户的问题的时候的效果 typed-js 官网typed 案例 2. 安装 CDN方式 这俩都可以,还有其…

18.springboot整合swagger

springboot整合swagger 引入依赖 <!--swagger--> <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version> </dependency> <dependency><groupId&…

Postman设置全部请求都携带请求头,Postman如何一次性设置请求头、不需要一个请求一个请求去添加请求头

文章目录 一、问题描述二、解决办法三、应用场景 一、问题描述 现在我有 n 个接口测试&#xff0c;其中 n 个都需要携带一致的请求头&#xff08;其实一般都是携带 JWT 令牌&#xff09;&#xff0c;怎么办&#xff1f;我要一个一个写&#xff1f;如图&#xff1a; 二、解决办…

添加sidecar容器并输出日志

添加一个sidecar容器(使用busybox 镜像)到已有的pod 11-factor-app中,确保sidecar容器能够输出/var/log/11-factor-app.log的信息,使用volume挂载/var/log目录,确保sidecar能访问11-factor-app.log 文件 # 准备工作 创建一个 pod 11-factor-appapiVersion: v1 kind: Pod metada…

PDF管理器和查看器PdfDing

什么是 PdfDing &#xff1f; PdfDing 是一款自托管 PDF 管理器和查看器&#xff0c;可在多种设备上提供无缝用户体验。它设计精简、速度快&#xff0c;并且易于通过 Docker 设置。 功能特点 在多种设备上无缝基于浏览器的 PDF 查看使用标签整理 PDF干净且响应迅速的用户界面暗…

VulnHub:colddbox easy

靶机下载地址 信息收集 主机发现 攻击机网段192.168.31.0/24&#xff0c;扫描同网段存活主机。 nmap 192.168.31.0/24 -Pn -T4 发现靶机&#xff0c;IP为192.168.31.176。 端口扫描 扫描靶机开放端口。 nmap 192.168.31.176 -A -p- -T4 开放了80,4512端口&#xff0c;注…

Prometheus安装部署

文章目录 1.Prometheus(普罗米修斯)安装部署1.1部署环境准备1.2部署prometheus1.3主机数据展示 2.Grafana安装部署2.1部署Grafana2.2配置Grafana数据源2.2配置Grafana仪表板 3.AlertManager安装部署3.1部署alertmanager3.2告警邮件发送配置3.3测试邮件告警效果3.4自定义邮件告警…

ModuleNotFoundError: No module named ‘py3langid‘ 以及如何将包安在虚拟环境下

前提&#xff1a;已经安装过改包&#xff08;pip install py3langid&#xff09;&#xff0c;但仍报错 原因&#xff1a;安装在其他目录下了 解决办法&#xff1a; 1、再次在终端输入pip install py3langid 显示安装位置 Requirement already satisfied: py3langid in c:\…

【ESP8684————固件烧录说明、调试记录(1)】

环境&#xff1a; 硬件&#xff1a;ESP8684 模块 芯片&#xff1a;ESP8684-MINI-1U 固件&#xff1a;ESP32-C2-4MB-AT-V3.3.0.0 固件烧录及烧录说明整理&#xff1a;固件及烧录说明整理 一、调试笔记&#xff1a; 1&#xff09;关于ESP8684模块&#xff08;ATCWMODE&#xf…

Jmeter三种方式获取数组中多个数据并将其当做下个接口参数入参【附带JSON提取器和CSV格式化】

目录 一、传统方式-JOSN提取器获取接口返回值 1、接口调用获取返回值 2、添加JSON提取器 3、调试程序查看结果 4、添加循环控制器 5、设置count计数器 6、添加请求 7、执行请求 二、CSV参数化 1、将结果写入后置处理程序 2、设置循环处理器 3、添加CSV文件 4、设置…