前端登录注册流程
前端注册流程
- 一、 请求工具文件 (`request.js`)
- 目的
- 关键点
- 二、 用户注册服务 (`user.js`)
- 关键点
- 关于 `URLSearchParams`
- 三、Vue组件代码
- 1.数据绑定与表单模型 (`registerData`)
- 2.表单验证规则 (`rules`)
- 3.自定义验证函数 (`checkRePassword`)
- 4.异步注册与登录功能 (`register`, `login`)
- 关于 `async/await` 语法
- 5.导入Token与路由 (`useRouter`, `useTokenStore`)
- 四、 优化部分
- 1.优化axios请求拦截器
- 总结
- 整个注册流程如下:
一、 请求工具文件 (request.js)
//定制axios实例配置 //导入axios npm install axios import axios from 'axios'; import { ElMessage } from 'element-plus'; // 定义基础URL const baseURL = '/api'; // 创建axios实例 const instance = axios.create({ baseURL, }); // 添加响应拦截器 instance.interceptors.response.use( response => { // 操作成功 // 如果后端返回的code为0,表示请求成功 if(response.data.code === 0) { return response.data; } // 操作失败 // 显示错误信息并返回Promise.reject,让外部可以捕获错误 ElMessage.error(response.data.msg || '服务异常'); return Promise.reject(response.data); }, error => { // 处理请求错误 ElMessage.error('服务异常'); return Promise.reject(error); } ); export default instance;
目的
封装HTTP请求逻辑,以便在整个项目中复用,简化与后端服务器的交互。
(图片来源网络,侵删)关键点
- 导入axios: 首先,通过import axios from 'axios';导入了axios库,这是一个流行的HTTP客户端,用于浏览器和node.js中发送HTTP请求。
- 定义baseURL: 设置了baseURL变量,通常指向后端API的基础路径,比如'/api',这样在每次请求时不需要重复书写这部分URL。
- 创建axios实例: 通过axios.create({baseURL})创建了一个axios实例,并设置了基础URL。
- 响应拦截器: 添加了一个响应拦截器,作用是在每个响应到达之后自动处理。如果响应成功,直接返回响应体中的数据(result.data);如果响应失败,则弹出错误提示,并通过Promise.reject(err)确保错误可以被外部捕获处理。
- 导出实例: 文件最后导出了这个定制的axios实例,供其他地方使用。
二、 用户注册服务 (user.js)
//导入request.js请求工具 import request from '@/utils/request.js' // import { pa } from 'element-plus/es/locale'; //提供调用注册接口的函数 export const userRegisterService = (registerData) => { //借助UslSearchParams对象完成传递 const params = new URLSearchParams() for(let key in registerData){ /** * params将registerData对象中的每个键值对添加为URL查询字符串的形式 * 这是许多后端API期望的POST请求数据格式。 */ params.append(key,registerData[key]) } /** *使用request.js中创建的axios实例,发起一个POST请求到/user/register端点将params作为请求体发送。 */ return request.post('/user/register',params); } //提供调用登录接口函数 export const userLoginService = (loginData) =>{ const params = new URLSearchParams() for(let key in loginData){ params.append(key,loginData[key]) } return request.post('/user/login',params); }
目的: 提供一个具体的函数来处理用户注册逻辑,包括构造请求参数、调用HTTP请求并返回结果。
关键点
- 导入request: request.js文件通常包含了axios实例的配置和创建,这里的import request from '@/utils/request.js'引入了这个配置好的axios实例,方便发起HTTP请求。
- userRegisterService函数:这个函数接收一个registerData对象,包含用户注册所需的所有信息(如用户名、密码等)。它将这些数据转换成URLSearchParams对象,这是HTTP POST请求常见的一种数据格式。
- URLSearchParams:new URLSearchParams()创建了一个新的搜索参数对象,params.append(key, registerData[key])将registerData对象的每个键值对添加到这个对象中。
- 发起POST请求:request.post('/user/register', params)使用导入的axios实例发起POST请求,'/user/register'是后端注册接口的URL,params是请求体,包含了用户注册的数据。
- userLoginService函数:与userRegisterService类似,但目标URL是'/user/login',用于处理用户登录。
- 返回Promise:两个函数都返回了axios实例的post方法返回的Promise,这使得在调用这些服务的地方可以通过.then()或async/await语法处理响应数据和错误。
- 模块导出:export关键字使得这些服务可以被其他模块导入和使用,如Vue组件或其他业务逻辑文件。
关于 URLSearchParams
URLSearchParams 是一个Web API,用于处理URL的查询字符串。它的作用是将对象转换成URL查询字符串的形式,这对于发送POST请求时需要序列化表单数据非常有用,特别是当后端期望接收表单格式的数据时。
- 创建实例: const params = new URLSearchParams(); 创建了一个新的 URLSearchParams 实例。
- 循环添加键值对: for(let key in registerData){ params.append(key,registerData[key]) } 这段代码遍历了 registerData 对象的所有属性,对于每个属性(键值对),它使用 append 方法将键和值添加到 URLSearchParams 实例中。这样做可以确保数据以正确的格式(键值对)附加到请求中,适合于表单提交的场景。
URLSearchParams 的使用是为了正确构造请求体,以适应后端接口对数据格式的要求,特别是在使用 Content-Type: application/x-www-form-urlencoded 的情况下,这是很多后端API在处理表单提交时的标准格式。
三、Vue组件代码
1.数据绑定与表单模型 (registerData)
- registerData 是一个响应式引用 (ref),用于存储用户输入的用户名、密码和确认密码。使用 v-model 指令将其与表单输入元素双向绑定,实现数据的实时同步。
//定义数据模型dev const registerData = ref({ username:'', password:'', rePassword:'' })
2.表单验证规则 (rules)
- rules 对象定义了表单字段的验证逻辑,包括是否必填、长度限制等。例如,用户名和密码都要求非空且长度在5到16个字符之间。对于确认密码字段,使用自定义验证函数 checkRePassword 确保与密码一致。
//定义表单校验规则 /** * 当用户在输入密码确认字段时触发 blur 事件,checkRePassword 函数会被调用 * 比较当前输入的 rePassword 值和 registerData.value.password(即用户初次输入的密码) */ const rules = { username:[ {required:true,message:'请输入用户名',trigger:'blur'}, {min:5,max:16,message:'长度为5~16位非空字符',trigger:'blur'} ], password:[ {required:true,message:'请输入密码',trigger:'blur'}, {min:5,max:16,message:'长度为5~16位非空字符',trigger:'blur'} ], rePassword:[ {validator:checkRePassword,trigger:'blur'} ] }
3.自定义验证函数 (checkRePassword)
- 此函数作为确认密码字段的验证器,比较用户输入的确认密码与原始密码是否匹配。如果不匹配或为空,则通过 callback 传入错误信息。
//自定义密码校验函数 /** * value 的值取决于调用 checkRePassword 函数时传入的参数。 * 在表单验证过程中value:表示用户在rePassword字段,是用户输入的“确认密码”的值。 * registerData.value.password 是 password 字段的值,它们都是 ref 对象的值,也是用户之前输入的“密码”的值 */ const checkRePassword = (rule,value,callback) =>{ if(value === '' ){ callback(new Error('请再次输入密码')) }else if(value != registerData.value.password){ callback(new Error('两次输入密码不一致')) }else{ callback() } }
4.异步注册与登录功能 (register, login)
- 这两个函数分别处理注册和登录的业务逻辑,通过调用后端API (userRegisterService, userLoginService) 来实现。它们都是异步操作,使用 await 关键字等待结果,然后根据服务器响应展示消息或执行后续操作,如路由跳转、保存token等。
//调用后台接口需要导入它的方法 // userRegisterService这个函数用于向后端发起用户注册请求。 // userLoginService这个函数用于向后端发起用户登录请求。 import { userRegisterService,userLoginService} from '@/api/user.js' // 定义一个异步的注册函数 const register = async () => { /** * 在事件监听器的回调函数中,调用register异步函数,通过await * 等待userRegisterService(registerData.value)的结果。 */ let result = await userRegisterService(registerData.value); ElMessage.success(result.msg?result.msg:'注册成功') // alert(result.msg || '注册成功'); // if (result.code === 0) { // alert(result.msg || '注册成功'); // } else { // alert('注册失败'); // } } //导入路由,进行登陆成功跳转 import { useRouter } from 'vue-router' //导入token import { useTokenStore} from '@/stores/token.js' //创建路由 const router = useRouter(); //创建token存储 const tokenStore = useTokenStore(); const login =async () => { //调用登录接口 let result = await userLoginService(registerData.value); ElMessage.success(result.msg?result.msg:'登录成功') //路由跳转当前根路径'/' router.push('/') //保存token存储到pinia tokenStore.setToken(result.data); }
关于 async/await 语法
async 和 await 是JavaScript中用于处理异步操作的关键词,它们让异步代码的编写更加直观和易于理解。
- async: 当声明一个函数为 async 时,这个函数会隐式地返回一个 Promise。这意味着你可以使用 await 关键字在这个函数内部等待 Promise 的解决,而无需显式地写出 .then() 或 .catch() 方法。这使得异步代码看起来更像是同步代码,提高了代码的可读性和可维护性。
- await: 只能在 async 函数内部使用。当你在一个 await 表达式前等待一个 Promise 时,代码会暂停在那一点,直到那个 Promise 解决(resolve),然后继续执行并返回 Promise 的解决值。如果 Promise 被拒绝(reject),则 await 表达式会抛出一个错误,可以在 async 函数中用 try...catch 来捕获这个错误。
在注册功能代码中,async 函数 register 负责处理整个注册流程,它通过 await userRegisterService(registerData.value) 来等待用户注册服务的响应,这使得代码在等待响应时不会阻塞其他任务的执行。
5.导入Token与路由 (useRouter, useTokenStore)
- 导入所需库和组件:useRouter 从 ‘vue-router’ 导入,用于获取和操作当前的路由实例。useTokenStore 从 ‘pinia’ 导入,用于访问和操作token的状态管理。
- 获取路由实例:const router = useRouter() 创建并获取当前应用的路由实例。
- 获取token状态管理:const tokenStore = useTokenStore() 创建并获取token的store实例。
- 路由跳转:router.push('/') 登录成功后,将用户重定向到应用的主页面(通常是 '/ 或者其他需要身份验证的页面)。
- 保存token:tokenStore.setToken(result.data); 保存服务器返回的token到token store中,假设result.data包含token信息。
index.js:配置(router):
//导入路由,进行登陆成功跳转 import { useRouter } from 'vue-router' //导入token import { useTokenStore} from '@/stores/token.js' //创建路由 const router = useRouter(); //创建token存储 const tokenStore = useTokenStore(); const login =async () => { //调用登录接口 let result = await userLoginService(registerData.value); ElMessage.success(result.msg?result.msg:'登录成功') router.push('/') //保存token存储到pinia tokenStore.setToken(result.data); }
Token.js:配置:
import { defineStore } from "pinia" import {ref} from 'vue'; /** * 第一个参数:名字,唯一 * 第二个参数:函数,函数的内部可以定义状态的所有内容 */ export const useTokenStore = defineStore('token',()=>{ //定义状态内容 //1.响应式变量 const token = ref('') //2.定义一个函数,修改token的值 const setToken = (newToken)=>{ token.value = newToken } //3.移除token的值 const removeToken = ()=>{ token.value = '' } return{ token,setToken,removeToken } })
四、 优化部分
1.优化axios请求拦截器
request.js:
//添加请求拦截器 instance.interceptors.request.use( //接收一个参数config,它是即将发出的HTTP请求的配置对象 (config)=>{ // 请求前的回调 const tokenStore = useTokenStore (); if(tokenStore.token){ //它检查了tokenStore是否存在token,如果存在,则将其添加到请求头的Authorization字段 config.headers.Authorization = tokenStore.token; } return config; }, (error)=>{ //请求错误的回调 Promise.reject(error) } )
Article.js:
//文章分类查询 export const ArticleCategoryListService = () =>{ /** *服务器验证:服务器收到请求后,会检查Authorization头中的token是否有效。 *如果服务器验证通过,它会返回文章分类的列表。 *如果验证失败,服务器可能会返回一个错误响应,例如401(未经授权)或403(禁止访问)。 */ return request.get('/category') }
总结
前端注册流程主要分为三个部分:请求工具文件(request.js)、用户注册服务(user.js)以及Vue组件中的相关逻辑。以下是整个流程的关键点和总结:
- 请求工具文件 (request.js):
- 创建了一个axios实例,设置了基础URL,并添加了响应拦截器来处理成功和失败的响应。
- 这个配置好的axios实例可以用于发起HTTP请求,简化与后端服务器的交互。
- 用户注册服务 (user.js):
- 提供了userRegisterService函数,它接收用户注册信息并构造POST请求,将数据转换成URLSearchParams对象发送到后端的注册接口。
- 同时提供了userLoginService函数,处理用户登录请求。
- Vue组件中的逻辑:
- registerData是一个响应式对象,用于存储用户在表单中输入的注册信息,与表单元素双向绑定。
- rules定义了表单验证规则,包括必填、长度限制等。
- checkRePassword是自定义验证函数,用于检查确认密码是否与原始密码一致。
- register和login是异步函数,负责调用注册和登录服务,处理响应并显示消息,成功后可能进行路由跳转和保存token。
- Token管理:
- 使用Pinia库定义了useTokenStore,管理token的状态,包括设置、获取和移除token。
整个注册流程如下:
- 用户在前端界面填写注册信息,这些信息被实时绑定到registerData对象。
- 用户点击注册按钮,触发register函数,该函数构造注册数据并调用userRegisterService。
- userRegisterService发送POST请求到后端的注册接口。
- 后端验证用户信息,如果成功则返回成功响应,前端收到响应后显示成功消息,并可能进行其他操作,如跳转。
- 如果注册失败,后端返回错误信息,前端会显示错误提示。
类似地,登录流程与注册类似,只是调用了userLoginService,成功后通常会保存token,并进行路由跳转至主页面
- 这两个函数分别处理注册和登录的业务逻辑,通过调用后端API (userRegisterService, userLoginService) 来实现。它们都是异步操作,使用 await 关键字等待结果,然后根据服务器响应展示消息或执行后续操作,如路由跳转、保存token等。
- 此函数作为确认密码字段的验证器,比较用户输入的确认密码与原始密码是否匹配。如果不匹配或为空,则通过 callback 传入错误信息。
- rules 对象定义了表单字段的验证逻辑,包括是否必填、长度限制等。例如,用户名和密码都要求非空且长度在5到16个字符之间。对于确认密码字段,使用自定义验证函数 checkRePassword 确保与密码一致。
- registerData 是一个响应式引用 (ref),用于存储用户输入的用户名、密码和确认密码。使用 v-model 指令将其与表单输入元素双向绑定,实现数据的实时同步。
- 整个注册流程如下: