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) => {
		// 在发送请求之前做些什么 token
		if (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 对象,直接添加到 FormData
        fd.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 plus
    AutoImport({
      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-password
            autocomplete="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="输入验证码" clearable
            maxlength="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) return
  formEl.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
    },

  },
})

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

九州金榜如何高质量培养孩子成长

在这个时代&#xff0c;孩子们就像温室里的花朵&#xff0c;被父母和家人宠爱着&#xff0c;享受着最优越的物质条件。 然而&#xff0c;在这样的环境中成长起来的孩子&#xff0c;却往往被很多父母称为"白眼狼"&#xff0c;对孩子的自私行为感到痛苦和失落。 1 随…

将 OpenCV 与 Eclipse 一起使用(插件 CDT)

先决条件 两种方式&#xff0c;一种是直接形成项目&#xff0c;另一种是 CMake 先决条件 在您的工作站中安装了 Eclipse&#xff08;只需要 C/C 的 CDT 插件&#xff09;。您可以按照以下步骤操作&#xff1a; 转到 Eclipse 站点下载面向 C/C 开发人员的 Eclipse IDE。根据您…

LT8911EX LVDS 转 eDP

概述 Lontium LT8911EX 是 LVDS 至 eDP 转换器&#xff0c;具有单端口或双端口可配置 LVDS 接收器&#xff0c;具有 1 个时钟通道和多达 8 个数据通道&#xff0c;每个数据通道的最大工作速率为 1.2Gbps&#xff0c;最大输入带宽为 9.6Gbps。该转换器对输入LVDS数据进行反串行…

TikTok云手机:突破传统社媒营销方式的黑科技

随着TikTok成为全球短视频领域的佼佼者&#xff0c;更多的企业和个人希望借助这个平台获得曝光和用户黏性。在这个背景下&#xff0c;TikTok云手机应运而生&#xff0c;为用户提供了更为便捷、高效的社交媒体运营方式。接下来&#xff0c;我们将深入剖析TikTok云手机的神奇之处…

深度学习技巧应用32-在YOLOv5模型上使用TensorRT进行加速的应用技巧

大家好,我是微学AI,今天给大家介绍一下深度学习技巧应用32-在YOLOv5模型上使用TensorRT进行加速的应用技巧,TensorRT是NVIDIA公司提供的一个深度学习推理(inference)优化器和运行时库。它专门为生产环境下的高性能深度学习推理提供优化支持。TensorRT可以加速深度学习模型…

安全漏洞周报(2024.01.01-2023.01.08)

漏洞速览 ■ 用友CRM系统存在逻辑漏洞 漏洞详情 1. 用友CRM系统存在逻辑漏洞 漏洞介绍&#xff1a; 某友CRM系统是一款综合性的客户关系管理软件&#xff0c;旨在帮助企业建立和维护与客户之间的良好关系。它提供了全面的功能&#xff0c;包括销售管理、市场营销、客户服…

AWS简介(Amazon Web Services )想使用怎么办?

Amazon Web Services&#xff08;AWS&#xff09;是由亚马逊公司提供的云计算平台和服务。AWS提供了一系列基础设施服务&#xff0c;包括计算能力、存储选项、数据库、机器学习、分析、物联网、安全性等&#xff0c;帮助组织和开发者建立和管理他们的应用。 以下是AWS的一些关…

如何用GPT写代码?

详情点击链接&#xff1a;如何用GPT写代码&#xff1f; 一OpenAI 1.最新大模型GPT-4 Turbo 2.最新发布的高级数据分析&#xff0c;AI画图&#xff0c;图像识别&#xff0c;文档API 3.GPT Store 4.从0到1创建自己的GPT应用 5. 模型Gemini以及大模型Claude2二定制自己的GPTs…

芯课堂 | SWM341系列屏驱应用之素材篇

今天小编给大家带来的是SWM341系列芯片在屏驱应用下对于素材预处理环节的详细介绍&#xff1a; 其中图片与字体是依托 LVGL 生态构建&#xff0c;而音视频是与 SWM341 的外设密切相关。 01.图片预处理 输出数据格式&#xff1a;Binary RGB565&#xff08;Swap&#xff09;or …

springboot私人健身与教练预约管理系统源码和论文

随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&#xf…

汽车产线设备CAN总线一键刷写方案

汽车产线设备CAN总线一键刷写方案 一、概述 随着汽车工业的不断发展&#xff0c;CAN总线技术在汽车产线设备中得到了广泛应用。然而&#xff0c;在实际生产过程中&#xff0c;设备的软件升级和配置更改是不可避免的。为了提高生产效率&#xff0c;我们推出了一键刷写CAN总线解…

HarmonyOS 开发基础(八)Row和Column

HarmonyOS 开发基础&#xff08;八&#xff09;Row和Column 一、Column 容器 1、容器说明&#xff1a; 纵向容器主轴方向&#xff1a;从上到下纵向交叉轴方向&#xff1a;从左到右横向 2、容器属性&#xff1a; justifyContent&#xff1a;设置子元素在主轴方向的对齐格式…

应用GIS进行生态敏感性评价

生态环境敏感性是指生态系统对区域内自然和人类活动干扰的敏感程度&#xff0c;它反映区域生态系统在遇到干扰时&#xff0c;发生生态环境问题的难易程度和可能性的大小&#xff0c;并用来表征外界干扰可能造成的后果。即在同样干扰强度或外力作用下&#xff0c;各类生态系统出…

Qt中QGraphicsView总体架构学习

前沿 前段时间学习了下如何在QGraphicsView架构中绘制刻度尺&#xff0c;主要是与OnPainter中进行比较的&#xff0c;那么今天就来详细讲解下我对QGraphicsView框架的认知吧~ 最近一段时间想学习下&#xff0c;如果我有不正确的&#xff0c;欢迎留言探讨哟~ QGraphicsView架…

页面无缘无故出现数字(Smarty的模板使用)

出现的数字是定义的用户的每条数据的排序&#xff0c;就像这个页面的第一个用户有10条数据01234569 目的是为了合并用户的单元格 解决&#xff1a;

多机TCP通讯之hello world(C++)

文章目录 TCP是什么准备工作CMakeLists.txt服务端代码客户端代码参考 TCP是什么 TCP&#xff08;传输控制协议&#xff09;是一种在计算机网络中广泛使用的协议&#xff0c;它提供了可靠的、面向连接的数据传输服务。TCP 是 OSI 模型中的传输层协议&#xff0c;它确保了数据的…

ChatGPT本地部署,学习记录

一、GPT4ALL模型 官网地址&#xff1a; Github&#xff1a;https://github.com/nomic-ai/gpt4all GPT4ALL项目部署简易&#xff0c;但是在运行体验上一般&#xff0c;并且是只调用CPU来进行运算。 看官方文档介绍在嵌入式上有比较大的优势&#xff0c;但是目前个人对嵌入式…

解锁Python库中操作系统级别模块psutil

目录 一、psutil库简介 二、安装psutil库 三、获取系统信息 1、获取CPU信息&#xff1a; 2、获取内存信息&#xff1a; 3、获取磁盘信息&#xff1a; 4、获取网络信息&#xff1a; 四、进程管理 五、系统信息和监控 六、总结 随着Python的普及&#xff0c;越来越多的…

2024年美赛数学建模思路 - 复盘:光照强度计算的优化模型

文章目录 0 赛题思路1 问题要求2 假设约定3 符号约定4 建立模型5 模型求解6 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 问题要求 现在已知一个教室长为15米&#xff0c;宽为12米&…

13.若依代码自动生成功能详解

文章目录 1.代码自动生成功能2.功能的使用3. 代码的导出和使用 1.代码自动生成功能 基于若依的目录结构&#xff0c;若依本身提供了代码生成功能&#xff0c;可以根据数据库表的内容&#xff0c;生成一些基本的CRUD的前后端的功能。本文将生成过程中的一些注意事项&#xff0c…