vue3 +TS axiox接口模块添加,fast mock接口访问测试

目录

一.接口地址

二.apipost 接口测试,能否接通

三.安装axiox

1.下载安装依赖

2.新建src/utils/request.ts文件

2.1解释:后续后端真实接口需要替换baseURL,目前没有使用配置文件,后续更换

3.新建src/utils/storage.ts文件

4.新建src/utils/formDataFormat.ts文件,

5.修改vite.config.ts文件,添加代理转发

5.1解释:后面后端真实接口直接替换即可

6.新建src/api/login 文件夹

 7.目录结构

二.测试使用

1.修改login.vue文件

2.测试效果

三.一些说明修改

1.stores/interface/index.ts修改

2.stores/states.ts修改


一.接口地址

fastmock接口项目地址:

https://www.fastmock.site/mock/b9536a1dea3fe4daeec18bc365e14a18/api

登录接口 ,完整引用路径(apipost测试时使用):

https://www.fastmock.site/mock/b9536a1dea3fe4daeec18bc365e14a18/api/login

相对路径,后面在api/login/index.ts里使用

/login

二.apipost 接口测试,能否接通

进入软件,新建一个接口即可,测试如下

登录信息,注意是body的raw的json格式

{

    "username":"admin",

    "password":"admin"

}

三.安装axiox

1.下载安装依赖

npm install axios
npm install @types/axios --save-dev用来使用Cookie
npm install js-cookie
npm install @types/js-cookie --save-dev

2.新建src/utils/request.ts文件

根据需求,相应的更改

2.1解释:后续后端真实接口需要替换baseURL,目前没有使用配置文件,后续更换

import axios from 'axios';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Session } from '@/utils/storage';// 配置新建一个 axios 实例
const service = axios.create({baseURL: 'https://www.fastmock.site/mock/b9536a1dea3fe4daeec18bc365e14a18/api',timeout: 50000,headers: { 'Content-Type': 'application/json' },
});// 添加请求拦截器
service.interceptors.request.use((config) => {// 在发送请求之前做些什么 tokenif (Session.get('token')) {(<any>config.headers).common['token'] = `${Session.get('token')}`;}return config;},(error) => {// 对请求错误做些什么return Promise.reject(error);}
);// 添加响应拦截器
service.interceptors.response.use((response) => {// 对响应数据做点什么const res = response.data;if (res.code && res.code !== '2000') {// `token` 过期或者账号已在别处登录if (res.code === 401 || res.code === "4001") {Session.clear(); // 清除浏览器全部临时缓存window.location.href = '/'; // 去登录页ElMessageBox.alert('你已被登出,请重新登录', '提示', {}).then(() => {}).catch(() => {});}return response.data;// return Promise.reject(service.interceptors.response);} else {return response.data;}},(error) => {// 对响应错误做点什么if (error.message.indexOf('timeout') != -1) {ElMessage.error('网络超时');} else if (error.message == 'Network Error') {ElMessage.error('网络连接错误');} else {if (error.response.data) ElMessage.error(error.response.statusText);else ElMessage.error('接口路径找不到');}return Promise.reject(error);}
);// 导出 axios 实例
export default service;

3.新建src/utils/storage.ts文件

持久化处理

import Cookies from 'js-cookie';/*** window.localStorage 浏览器永久缓存* @method set 设置永久缓存* @method get 获取永久缓存* @method remove 移除永久缓存* @method clear 移除全部永久缓存*/
export const Local = {// 设置永久缓存set(key: string, val: any) {window.localStorage.setItem(key, JSON.stringify(val));},// 获取永久缓存get(key: string) {let json: any = window.localStorage.getItem(key);return JSON.parse(json);},// 移除永久缓存remove(key: string) {window.localStorage.removeItem(key);},// 移除全部永久缓存clear() {window.localStorage.clear();},
};/*** window.sessionStorage 浏览器临时缓存* @method set 设置临时缓存* @method get 获取临时缓存* @method remove 移除临时缓存* @method clear 移除全部临时缓存*/
export const Session = {// 设置临时缓存set(key: string, val: any) {if (key === 'token') return Cookies.set(key, val);window.sessionStorage.setItem(key, JSON.stringify(val));},// 获取临时缓存get(key: string) {if (key === 'token') return Cookies.get(key);let json: any = window.sessionStorage.getItem(key);return JSON.parse(json);},// 移除临时缓存remove(key: string) {if (key === 'token') return Cookies.remove(key);window.sessionStorage.removeItem(key);},// 移除全部临时缓存clear() {Cookies.remove('token');window.sessionStorage.clear();},
};

4.新建src/utils/formDataFormat.ts文件,

处理访问接口时传递参数格式

export function objectToFormData(obj: Record<string, any>, form?: FormData, namespace?: string): FormData {const fd = form || new FormData();let formKey: string;for (const property in obj) {if (obj.hasOwnProperty(property)) {const key = Array.isArray(obj) ? '[]' : `[${property}]`;if (namespace) {formKey = `${namespace}${key}`;} else {formKey = property;}// 如果属性是对象,但不是 File 对象,则递归调用 objectToFormData 处理嵌套对象if (typeof obj[property] === 'object' && !(obj[property] instanceof File)) {objectToFormData(obj[property], fd, formKey);} else {// 如果属性值是字符串或 File 对象,直接添加到 FormDatafd.append(formKey, obj[property]);}}}return fd;
}

5.修改vite.config.ts文件,添加代理转发

5.1解释:后面后端真实接口直接替换即可

添加部分

 server: {host: '0.0.0.0',port: 5000,open: true,proxy: {'/api': {target: 'https://www.fastmock.site/mock/b9536a1dea3fe4daeec18bc365e14a18/api',ws: true,changeOrigin: true,rewrite: (path) => path.replace(/^\/api/, ''),},},},

目前为止的完整文件内容

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'// 以下为按需导入,自动引入手动导入element plus
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
//手动导入element plus 时
// import ElementPlus from 'unplugin-element-plus/vite'// https://vitejs.dev/config/
export default defineConfig({plugins: [vue(),// ElementPlus({// } ),//手动导入element plus 时// 以下为按需导入,自动引入手动导入element plusAutoImport({resolvers: [ElementPlusResolver()],}),Components({resolvers: [ElementPlusResolver()],}),],resolve: {extensions: ['.vue', '.ts'],alias: {"@": path.resolve(__dirname, "src"),}},server: {host: '0.0.0.0',port: 8888,open: true,proxy: {'/api': {target: 'https://www.fastmock.site/mock/b9536a1dea3fe4daeec18bc365e14a18/api',ws: true,changeOrigin: true,rewrite: (path) => path.replace(/^\/api/, ''),},},},
})

 

6.新建src/api/login 文件夹

新建src/api/login/index.ts文件以及src/api/login/types.ts文件

// login/index.ts
import request from '@/utils/request';
import { objectToFormData } from "@/utils/formDataFormat";// post请求参数是form-data时,使用此方法处理数据
import { LoginState } from './types';/*** 登录api接口集合* @method login用户登录* @method logout用户退出登录*/
export function UseLoginApi() {return {login: (params: LoginState) => {return request({url: '/login',method: 'post',data: objectToFormData(params),});},// logout: (params: object) => {// 	return request({// 		url: '/logout',// 		method: 'post',// 		data: objectToFormData(params),// 	});// },};
}
// login/types.ts
// 登录参数类型
export interface LoginState{username:string;password:string
}
// 拿到的用户数据类型定义
export interface UserInfoState{user:string;ID:string;age:string | number ;sex:string
}

 7.目录结构

二.测试使用

1.修改login.vue文件

添加内容

import { UseLoginApi } from "@/api/login/index"
import { LoginState } from "@/api/login/types";const useLoginApi = UseLoginApi()
const login = () => {let data: LoginState = {username: "admin",password: "admin"}useLoginApi.login(data).then((res) => {console.log(res);}).catch((err) => {console.log(err);})
}

完整login.vue文件内容

<template>部分

<template><div class="loginForm"><div class="rloginTitle">登录</div><!-- 各个输入框 --><el-form :model="state.formData" :rules="formRules" ref="formRef" label-width="50px"><el-form-item prop="username"><div class="formInput"><el-input v-model="state.formData.username" placeholder="username" clearable autocomplete="off"prefix-icon="User"></el-input></div></el-form-item><el-form-item prop="password"><div class="formInput"><el-input v-model="state.formData.password" placeholder="password" type="password" show-passwordautocomplete="off" prefix-icon="Lock"></el-input></div></el-form-item><!-- 验证码 --><el-form-item><div class="formInput codeLine"><el-input class="codeInput" @input="checkCodeFun" v-model="checkCode.code" placeholder="输入验证码" clearablemaxlength="4" /><slideVerify class="codeShow" v-model:identifyCode="identifyCode" @click="refresh()"></slideVerify></div></el-form-item><!-- 登陆界面 --><el-form-item><div class="formInput settings"><label class="labelText"><input type="checkbox" v-model="rem_pswd" /> 记住密码</label><label class="labelText"><span @click.stop="go_page('findPassword')">忘记密码?</span><span @click.stop="go_page('register')">注册</span></label></div></el-form-item><!-- 提交按钮 --><el-form-item label-width="0"><el-button :loading="state.loading" :disabled="!checkCode.isTrue" type="primary" class="loginButton" round@click="handleSubmita(formRef)">登录</el-button></el-form-item></el-form></div>
</template>

 后续

<script setup lang="ts">
import { UseLoginApi } from "@/api/login/index"
import { LoginState } from "@/api/login/types";const useLoginApi = UseLoginApi()
const login = () => {let data: LoginState = {username: "admin",password: "admin"}useLoginApi.login(data).then((res) => {console.log(res);}).catch((err) => {console.log(err);})
}import { reactive, ref } from 'vue';const state = reactive({loading: false,formData: {username: "admin",password: "admin"}
})
const formRef = ref<FormInstance>(); // 创建一个 ref 来引用表单
const formRules = reactive<FormRules<typeof state.formData>>({username: [{ required: true, message: 'Please input activity form', trigger: 'blur' }],password: [{ required: true, message: 'Please input activity form', trigger: 'blur' }],
})// 记住密码,true 或 false
const rem_pswd = ref(localStorage.getItem('rem_pswd'))const go_page = (path: string) => {router.push({name: 'login', // 替换为目标路由的名称或路径query: {path: path}})
}const handleSubmita = (formEl: FormInstance | undefined) => {if (!formEl) returnformEl.validate((valid: any, fields: any) => {if (valid) {login()console.log('login');} else {console.log('error submit!', fields)}})
}// 生成验证码以及检测
import slideVerify from "@/components/slideVerify.vue"
import { FormInstance, FormRules } from 'element-plus';
import router from '@/router';
interface CheckCodeType {code: string;isTrue: boolean;
}// 生成随机验证码
const generateCode = () => {const code = ref('');const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";for (let i = 0; i < 4; i++) {code.value += characters.charAt(Math.floor(Math.random() * characters.length));}return code.value;
}
// 传递 验证码给子组件
const identifyCode = ref(generateCode())
// 刷新验证码
const refresh = () => {identifyCode.value = generateCode()
}
// 检测输入的验证码,控制提交按钮是否可用
const checkCodeFun = (newValue: string) => {if ((newValue as string).toUpperCase() === identifyCode.value) {checkCode.isTrue = true} else {checkCode.isTrue = false}
}
const checkCode = reactive<CheckCodeType>({code: identifyCode.value,isTrue: false
})
</script><style scoped>
/* 可以添加一些样式 */
.loginForm {height: 400px;border: 1px solid;border-radius: 10px;text-align: center;background-color: #f3f3f3;
}.loginForm .rloginTitle {font-size: 23px;margin: 5%;
}.loginButton {width: 250px;margin: auto;margin-top: 20px;
}.formInput {width: 80%;min-width: 50px;
}.codeLine {display: flex;
}.codeLine .codeInput {flex: 2;}.codeLine .codeShow {flex: 1;}.settings {display: flex;justify-content: space-between;
}.settings label {flex: 1;font-size: 16px;
}.settings .labelText {cursor: pointer;
}.btn-base {width: 100%;
}.btn-flex {display: flex;justify-content: center;
}
</style>

目前来说,直接测试是有效果的

2.测试效果

点击登陆后,收到的数据打印成功,

 控制台-》网路查看,的确是访问了接口

三.一些说明修改

还记得之前安装pinia时,测试定义了一个userInfoState类型在stores/interface/index.ts里,

这个是用户信息的类型,我么这次转移到了api/login/types.ts里了,所以要有一些改动,

如果是跟接口访问的数据类型,或是接口返回的数据类型有关定义,我们可以在相应的

api/XXX/types.ts里定义,如果是其他的一些状态,我们再定义到stores/interface/index.ts里

1.stores/interface/index.ts修改

// 示例
export interface exampleState {parmas1:string;parmas2:string
} 

2.stores/states.ts修改

// 在 src/store/index.js 中创建一个简单的 store
import { UserInfoState } from '@/api/login/types';
import { defineStore } from 'pinia'interface State {userForm: UserInfoState;
}export const useMyStore = defineStore('myStore', {state: (): State => ({userForm: {user: '',ID: '',age: '',sex: ''},// 其他状态}),actions: {// 动作setUserInfo(data:UserInfoState) {this.userForm = data},},
})

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

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

相关文章

龍运当头--html做一个中国火龙祝大家龙年大吉

🐉效果展示 🐉HTML展示 <body> <!-- partial:index.partial.html --> <svg><defs><g id=

如何在一张图里同时显示两个三维图

import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3Dplt.rcParams["font.sans-serif"] ["SimHei"]# 正确显示中文和负号 plt.rcParams["axes.unicode_minus"] False# 创建数据 x np.random.rand(50…

006集 正则表达式 re 应用实例—python基础入门实例

正则表达式指预先定义好一个 “ 字符串模板 ” &#xff0c;通过这个 “ 字符串模 板” 可以匹配、查找和替换那些匹配 “ 字符串模板 ” 的字符串。 Python的中 re 模块&#xff0c;主要是用来处理正则表达式&#xff0c;还可以利用 re 模块通过正则表达式来进行网页数据的爬取…

TDengine 签约西电电力

近年来&#xff0c;随着云计算和物联网技术的迅猛发展&#xff0c;传统电力行业正朝着数字化、信息化和智能化的大趋势迈进。在传统业务基础上&#xff0c;电力行业构建了信息网络、通信网络和能源网络&#xff0c;致力于实现发电、输电、变电、配电和用电的实时智能联动。在这…

SpringBoot 启动流程

一、SpringBoot 启动流程主要可以概括为以下几个步骤&#xff1a; 加载启动类 当 SpringBoot 项目启动时&#xff0c;会在当前工作目录下寻找有SpringBootApplication注解标识的类&#xff0c;并把这个类作为应用程序的入口点。如果找不到这样的主类&#xff0c;则会打印错误信…

麒麟系统安装docker、mysql、clickhouse

1、查看麒麟系统版本信息 cat /etc/os-release 麒麟系统版本V10 64位操作系统 # uname -p x86_64 # uname -p aarch64 内核版本 # uname -r 4.19.90-24.4.v2101.ky10.x86_64 本操作为麒麟系统版本V10&#xff0c;x86_64操作系统 一&#xff0c;安装docker 文件&#xff1a…

CANoe中的signalGenerators

前言&#xff1a; SignalGenerators可以理解为一个简单的信号发生器&#xff0c;用户能够指定特定的信&#xff08;LDF,DBC,XML中定义的信号&#xff0c;用户自定义的系统变量&#xff0c;环境变量&#xff0c;和系统自带的环境变量&#xff09;按照指定的波形&#xff0c;输出…

不用下载的在线photoshop,谁能不爱!

多年来&#xff0c;Photoshop 一直是设计师的首选。Photoshop 的功能无疑是非常强大的。设计师可以使用它来制作从简单的网页到复杂的移动应用程序设计。学习 Photoshop 的基本知识很容易&#xff0c;但学习 Photoshop 的所有技能都需要大量的时间和精力。许多新的 UI 设计合作…

npm install node-sass安装失败的解决方案

解决方案 1. 检查node-sass安装版本是否正确。 本地安装的node版本不同&#xff0c;需要安装的node-sass版本也是不一样的。node-sass官方给出了不同版本的node和node-sass的对应关系&#xff0c;读者可访问node-sass github仓库或者node-sass npm仓库进行查看。 本地安装的n…

静态界面——倒计时

静态界面——倒计时 功能代码界面展示 功能代码 <!DOCTYPE html> <html><head><title>倒计时</title><style>body {font-family: Arial, sans-serif;text-align: center;}h1 {font-size: 80px;color: #ff0000;line-height: 40vh;}.topSty…

iOS快捷指令蓝牙开关

前提条件&#xff1a;手机系统蓝牙与目标设备蓝牙已配对 设置蓝牙执行总次数&#xff0c;修改执行的app&#xff0c;蓝牙当前每次断开重连是6s&#xff0c;执行5次发送通知&#xff0c;修改微信接受人。 主要适用于依赖蓝牙秒连的APP&#xff0c;压力测试。 下载地址

C语言如何提高程序的可读性?

一、问题 可读性是评价程序质量的一个重要标准&#xff0c;直接影响到程序的修改和后期维护&#xff0c;那么如何提高程序的可读性呢? 二、解答 提高程序可读性可以从以下几方面来进行。 &#xff08;1&#xff09;C程序整体由函数构成的。 程序中&#xff0c;main()就是其中…