前端登录注册流程

一、 请求工具文件 (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请求并返回结果。

关键点

  1. 导入request: request.js文件通常包含了axios实例的配置和创建,这里的import request from '@/utils/request.js'引入了这个配置好的axios实例,方便发起HTTP请求。
  2. userRegisterService函数:这个函数接收一个registerData对象,包含用户注册所需的所有信息(如用户名、密码等)。它将这些数据转换成URLSearchParams对象,这是HTTP POST请求常见的一种数据格式。
  3. URLSearchParamsnew URLSearchParams()创建了一个新的搜索参数对象,params.append(key, registerData[key])registerData对象的每个键值对添加到这个对象中。
  4. 发起POST请求request.post('/user/register', params)使用导入的axios实例发起POST请求,'/user/register'是后端注册接口的URL,params是请求体,包含了用户注册的数据。
  5. userLoginService函数:与userRegisterService类似,但目标URL是'/user/login',用于处理用户登录。
  6. 返回Promise:两个函数都返回了axios实例的post方法返回的Promise,这使得在调用这些服务的地方可以通过.then()async/await语法处理响应数据和错误。
  7. 模块导出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 语法

asyncawait 是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)

  1. 导入所需库和组件useRouter 从 ‘vue-router’ 导入,用于获取和操作当前的路由实例。useTokenStore 从 ‘pinia’ 导入,用于访问和操作token的状态管理。
  2. 获取路由实例const router = useRouter() 创建并获取当前应用的路由实例。
  3. 获取token状态管理const tokenStore = useTokenStore() 创建并获取token的store实例。
  4. 路由跳转router.push('/') 登录成功后,将用户重定向到应用的主页面(通常是 '/ 或者其他需要身份验证的页面)。
  5. 保存tokentokenStore.setToken(result.data); 保存服务器返回的tokentoken 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组件中的相关逻辑。以下是整个流程的关键点和总结:

  1. 请求工具文件 (request.js)
    • 创建了一个axios实例,设置了基础URL,并添加了响应拦截器来处理成功和失败的响应。
    • 这个配置好的axios实例可以用于发起HTTP请求,简化与后端服务器的交互。
  2. 用户注册服务 (user.js)
    • 提供了userRegisterService函数,它接收用户注册信息并构造POST请求,将数据转换成URLSearchParams对象发送到后端的注册接口。
    • 同时提供了userLoginService函数,处理用户登录请求。
  3. Vue组件中的逻辑
    • registerData是一个响应式对象,用于存储用户在表单中输入的注册信息,与表单元素双向绑定。
    • rules定义了表单验证规则,包括必填、长度限制等。
    • checkRePassword是自定义验证函数,用于检查确认密码是否与原始密码一致。
    • registerlogin是异步函数,负责调用注册和登录服务,处理响应并显示消息,成功后可能进行路由跳转和保存token。
  4. Token管理
    • 使用Pinia库定义了useTokenStore,管理token的状态,包括设置、获取和移除token。

整个注册流程如下:

  1. 用户在前端界面填写注册信息,这些信息被实时绑定到registerData对象。
  2. 用户点击注册按钮,触发register函数,该函数构造注册数据并调用userRegisterService
  3. userRegisterService发送POST请求到后端的注册接口。
  4. 后端验证用户信息,如果成功则返回成功响应,前端收到响应后显示成功消息,并可能进行其他操作,如跳转。
  5. 如果注册失败,后端返回错误信息,前端会显示错误提示。

类似地,登录流程与注册类似,只是调用了userLoginService,成功后通常会保存token,并进行路由跳转至主页面

  • 41
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值