前端注册流程
一、 请求工具文件 (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。
- 使用Pinia库定义了
整个注册流程如下:
- 用户在前端界面填写注册信息,这些信息被实时绑定到
registerData
对象。 - 用户点击注册按钮,触发
register
函数,该函数构造注册数据并调用userRegisterService
。 userRegisterService
发送POST请求到后端的注册接口。- 后端验证用户信息,如果成功则返回成功响应,前端收到响应后显示成功消息,并可能进行其他操作,如跳转。
- 如果注册失败,后端返回错误信息,前端会显示错误提示。
类似地,登录流程与注册类似,只是调用了userLoginService
,成功后通常会保存token
,并进行路由跳转至主页面