当前位置: 首页 > article >正文

Vue3+Vite+TypeScript+Element Plus开发-07.Mockjs引用与Axios封装

系列文档目录

Vue3+Vite+TypeScript安装

Element Plus安装与配置

主页设计与router配置

静态菜单设计

Pinia引入

Header响应式菜单缩展

Mockjs引用与Axios封装

登录设计

登录成功跳转主页

多用户动态加载菜单

Pinia持久化

动态路由-配置 


文章目录

目录

系列文档目录

文章目录

前言

一、Mockjs

二、axios

三、Aside调整

参考文献:


前言

Mock.js 是一个用于模拟数据的 JavaScript 库。它可以帮助开发者快速生成模拟数据,用于前端开发中的接口测试、页面展示等场景,从而避免因后端接口未完成而导致前端开发进度受阻。

Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 Node.js 环境。它提供了简单易用的 API,用于发送各种类型的 HTTP 请求,如 GET、POST、PUT、DELETE 等。


一、Mockjs

1.安装

npm install mockjs

2.mock模拟数据构建

2.1在src文件夹下新建文件夹mock

2.2在mock文件夹下新建文件夹mockData

2.3在mockData文件夹下新建文件menu.ts

完整代码:

// src/mock/mockData/menu.ts
import Mock from 'mockjs';
import { Document, Setting } from '@element-plus/icons-vue'; // 假设你使用的是 Element Plus 的图标// 模拟菜单数据
const menuData = Mock.mock({data: [{ index: 'Home', label: '首页', icon: Document },{index: 'SysSettings',label: '系统设置',icon: Setting,children: [{ index: 'UserInfo', label: '个人资料' },{ index: 'AccountSetting', label: '账户设置' },],},],
});export default menuData;

2.4.在mock文件夹下新建文件index.ts

// src/mock/index.ts
import Mock from 'mockjs';
import menuData from '@/mock/mockData/menuData';Mock.mock(/menu/, 'get', (req: any) => {return menuData.data;
});

3.Mock引用

3.1修改main.ts文件

重点部分:

// 引入 Mock 数据
import './mock'

完整代码:

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import router from './router';
import App from './App.vue'
import { createPinia } from 'pinia'
// 引入 Mock 数据
import './mock'// 创建 Pinia 实例
const pinia = createPinia();const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component)}app.use(ElementPlus, {locale: zhCn,})app.use(router);app.use(pinia);app.mount('#app')

二、axios

1.安装

npm install axios

2.axios封装

2.1在src文件夹下新建文件夹api

2.2在api下新建文件request.ts

在baseURL: 'http://127.0.0.1:5173' 根据实际情况填写,具体参考运行时候网址,待api数据可以的时候调整baseURL指向可以无缝隙切换(后续会增加正式区与测试区自行切换)

import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';// 创建 axios 实例
const instance: AxiosInstance = axios.create({baseURL: 'http://127.0.0.1:5173', // 'http://127.0.0.1:8080', // 替换为你的 API 基础地址timeout: 5000, // 请求超时时间headers: {'Content-Type': 'application/json'}
});// 请求拦截器
instance.interceptors.request.use((config: AxiosRequestConfig) => {// 在发送请求之前做些什么,例如添加 Tokenconst token = localStorage.getItem('token'); // 假设使用 localStorage 存储 tokenif (token) {config.headers['Authorization'] = `Bearer ${token}`;}// 增加 API KEYconst api_key = 'Test';if (api_key) {config.headers['api_key'] = `${api_key}`;}return config;},(error: AxiosError) => {// 对请求错误做些什么console.error('请求错误:', error);return Promise.reject(error);}
);// 响应拦截器
instance.interceptors.response.use((response: AxiosResponse) => {// 对响应数据做点什么return response.data; // 直接返回数据},(error: AxiosError) => {// 对响应错误做点什么if (error.response) {// 请求已发出,但服务器响应的状态码不在 2xx 范围内console.error('响应错误:', error.response);return Promise.reject(error.response.data); // 返回后端返回的错误数据} else if (error.request) {// 请求已发出,但没有收到响应console.error('请求错误:', error.request);return Promise.reject(error.request);} else {// 在设置请求时触发了错误console.error('请求设置错误:', error.message);return Promise.reject(error.message);}}
);// 封装常用的请求方法
export const request = (url: string, data: any = {}, method: string = 'GET') => {return instance({url,method,data: method.toUpperCase() === 'GET' ? null : data,params: method.toUpperCase() === 'GET' ? data : null});
};// 封装 POST 请求
export const post = (url: string, data: any = {}) => {return request(url, data, 'POST');
};// 封装 GET 请求
export const get = (url: string, params: any = {}) => {return request(url, params, 'GET');
};

在该项目中,表头新增api_key,可以根据实际情况进行删除或保留

    // 增加 API KEYconst api_key = 'Test';if (api_key) {config.headers['api_key'] = `${api_key}`;}

 2.3在api文件夹下新建menu.ts

// 引入 request、post 和 get 函数 
import { get } from '@/api/request'; // 绝对路径// 登录接口
export const menuAPI = async () => {try {const result = await get('/menu'); // 使用封装的 get 方法return result  ;} catch (error) {console.error('获取菜单数据失败:', error);return [];}
};

三、Aside调整

1.调整MainAsideCont.vue

menu数据原是引用固定,现改为引用api资料

/*
const menuData = ref<MenuItem[]>([{ index: 'Home', label: '首页', icon: Document },{index: 'SysSettings',label: '系统设置',icon: Setting,children: [{ index: 'UserInfo', label: '个人资料' },{ index: 'AccountSetting', label: '账户设置' },],},
]);
*/
// 确保 menuAPI 是一个数组,并赋值给 menuData
const menuData = ref<MenuItem[]>([]); // 初始化为空数组// 封装数据获取和处理逻辑
const fetchMenuData = async () => {try {const result = await menuAPI(); // 调用异步 API 获取数据console.error('menuAPI :', result);if (Array.isArray(result)) {menuData.value = result as MenuItem[]; // 确保结果是 MenuItem[] 类型} else {console.error('menuAPI 返回的数据不是数组:', result);}} catch (error) {console.error('获取菜单数据失败:', error);}
};

 完整代码:

<template> <el-menu:default-active="activeIndex"class="el-menu-vertical-demo":collapse="isCollapse"><h3 :key="TitleText">{{TitleText}}</h3><!-- 渲染没有子菜单的项 --><el-menu-itemv-for="item in noChilden":key="item.index":index="item.index"@click="handlemenu(item)"><component class="icon" :is="item.icon"></component><span>{{ item.label }}</span></el-menu-item><!-- 渲染有子菜单的项 --><el-sub-menuv-for="item in hasChilden":key="item.index":index="item.index"><template #title><component class="icon" :is="item.icon"></component><span>{{ item.label }}</span></template><el-menu-itemv-for="subItem in item.children":key="subItem.index":index="subItem.index"@click="handlemenuchild(item, subItem)"><span>{{ subItem.label }}</span></el-menu-item></el-sub-menu></el-menu>
</template><script lang="ts" setup>
import { ref, computed, onMounted } from 'vue';
import { defineComponent } from 'vue';
import { useRouter } from 'vue-router';
import {Document,Setting,
} from '@element-plus/icons-vue';import { useAllDataStore } from '@/stores';import { menuAPI } from '@/api/menu'; interface MenuItem {index: string;label: string;icon?: any;children?: MenuItem[];
}
/*
const menuData = ref<MenuItem[]>([{ index: 'Home', label: '首页', icon: Document },{index: 'SysSettings',label: '系统设置',icon: Setting,children: [{ index: 'UserInfo', label: '个人资料' },{ index: 'AccountSetting', label: '账户设置' },],},
]);
*/
// 确保 menuAPI 是一个数组,并赋值给 menuData
const menuData = ref<MenuItem[]>([]); // 初始化为空数组// 封装数据获取和处理逻辑
const fetchMenuData = async () => {try {const result = await menuAPI(); // 调用异步 API 获取数据console.error('menuAPI :', result);if (Array.isArray(result)) {menuData.value = result as MenuItem[]; // 确保结果是 MenuItem[] 类型} else {console.error('menuAPI 返回的数据不是数组:', result);}} catch (error) {console.error('获取菜单数据失败:', error);}
};onMounted(() => {fetchMenuData(); // 在组件挂载时调用 fetchMenuData 函数
});const hasChilden = computed(() => menuData.value.filter(item => item.children && item.children.length > 0));
const noChilden = computed(() => menuData.value.filter(item => !item.children || item.children.length === 0));const activeIndex = ref('Home');
const router = useRouter();const handlemenu = (item: MenuItem) => {router.push(item.index);
};const handlemenuchild = (item: MenuItem, subItem: MenuItem) => {  router.push(subItem.index);
};// const isCollapse = ref(true)
const store = useAllDataStore();
const TitleText = computed(() => {return store.isCollapse ? '平台' : '测试平台管理';
});const isCollapse = computed(() => store.isCollapse); 
/*
// 使用 defineComponent 显式命名组件
export const MainAsideCont = defineComponent({name: 'MainAsideCont'
});
*/</script><style>
.el-menu {height: 100%; /* 设置整个布局的高度为 100%,确保布局占满整个视口 */border-right: none; /* 去掉右边框 */
}
.el-menu-vertical-demo:not(.el-menu--collapse) {width: 180px;min-height: 400px;
}
.el-menu-vertical-demo.el-menu--collapse {width: 60px; /* 收缩时的宽度 */
}.icon {margin-right: 8px; /* 图标与文字之间的间距 */font-size: 18px;   /* 图标的大小 */width:18px;height:18px;size:8px;color: #606266;    /* 图标的默认颜色 */vertical-align: middle; /* 垂直居中对齐 */
}/* 鼠标悬停时的样式 */
.icon:hover {color: #409eff; /* 鼠标悬停时图标的颜色 */
}</style>

四 、运行效果

点击expand

菜单数据来源Mock模拟资料,也就是api资料。


参考文献:

  1. Axios 官方网址https://axios-http.com/
  2. Mockjs官方网址https://mockjs.com/

相关文章:

Vue3+Vite+TypeScript+Element Plus开发-07.Mockjs引用与Axios封装

系列文档目录 Vue3ViteTypeScript安装 Element Plus安装与配置 主页设计与router配置 静态菜单设计 Pinia引入 Header响应式菜单缩展 Mockjs引用与Axios封装 登录设计 登录成功跳转主页 多用户动态加载菜单 Pinia持久化 动态路由-配置 文章目录 目录 系列文档目…...

安全理念和安全产品发展史

从安全理念的发展历史来看,技术与产品的演进始终围绕 “威胁对抗” 与 “业务适配” 两大核心展开。以下从七个关键阶段解析安全技术与产品的发展脉络,并结合最新实践与未来趋势提供深度洞察: 一、密码学奠基阶段(1970s 前) 安全理念:以 “信息保密” 为核心,防御手段…...

【Redis】背景知识

一、Redis的特性 Redis是一种基于键值对&#xff08;key-value&#xff09;的NoSQL数据库&#xff0c;与很多键值对数据库不同的是&#xff0c;Redis中的值可以是由string&#xff08;字符串&#xff09;&#xff0c;hash&#xff08;哈希&#xff09;&#xff0c;list&#xf…...

Spring MVC 返回 JSON 视图的方式及对比(6种)

Spring MVC 返回 JSON 视图的方式及对比&#xff08;新增 MappingJackson2JsonView&#xff09; 1. 方式一&#xff1a;ResponseBody 注解 作用&#xff1a;直接返回对象&#xff0c;由消息转换器&#xff08;如 Jackson&#xff09;序列化为 JSON。 适用场景&#xff1a;简单…...

【Kafka基础】消费者命令行完全指南:从基础到高级消费

Kafka消费者是消息系统的关键组成部分&#xff0c;掌握/export/home/kafka_zk/kafka_2.13-2.7.1/bin/kafka-console-consumer.sh工具的使用对于调试、测试和监控都至关重要。本文将全面介绍该工具的各种用法&#xff0c;帮助您高效地从Kafka消费消息。 1 基础消费模式 1.1 从最…...

在 Vue 中监听常用按键事件(回车,ESC 键,空格等)。

一、Vue 原生按键修饰符&#xff08;推荐&#xff09; html <!-- 常用按键监听 --> <input keyup.enter"submit" <!-- 回车键 -->keydown.esc"cancel" <!-- ESC 键 -->keyup.space"togglePlay" <!-- 空格键…...

航电系统的任务载荷集成技术要点概述!

一、任务载荷集成技术难点 1. 接口标准化与兼容性 异构设备协议冲突&#xff1a;不同厂商的载荷设备&#xff08;如光学相机、雷达、电子战模块&#xff09;采用不同的通信协议&#xff08;如1553B、RS422、以太网&#xff09;&#xff0c;需设计统一的总线接口标准以支持即…...

OceanBase V4.3.5 上线全文索引功能,让数据检索更高效

近日&#xff0c;OceanBase 4.3.5 BP1 版本正式推出了企业级全文索引功能。该版本在中文分词、查询效率及混合检索能力上进行了全面提升。经过自然语言模式和布尔模式在不同场景下的对比测试&#xff0c;OceanBase 的全文索引性能明显优于 MySQL。 点击下载 OceanBase 社区版…...

Qt中的信号与槽及其自定义

信号源&#xff1a;哪个控件发的信号 信号的类型&#xff1a;用户进行不同的操作就会触发不同的信号 如点击按钮&#xff0c;在输入框移动光标&#xff0c;勾选一个复选框&#xff0c;选 择一个下拉框 信号的处理方式&#xff1a;槽(slot)----也就是函数&#xff0c;Qt中用con…...

【PFPGA学习】状态机思想编程HDLbitsFPGA练习

目录 一、用状态机实现LED流水灯 1.1状态机思想 1.2状态机思想LED流水灯 1.3 modesim仿真 1.4 FPGA烧录实现 二、CPLD和FPGA芯片 1. 核心结构与技术原理 2. 性能与容量 3. 适用场景 &#xff14;. 选型建议 三、HDLbitsFPGA练习记录&#xff08;combinational logic…...

Android 中集成 Unity 工程的步骤

在 Adroid 项目中集成 Unity 工程,主要步骤如下: 一、前提条件 1、已有一个 Android 工程项目; 2、Unity 工程已导出为 Android 工程,目录大概如下: 二、集成步骤 1、在 Android 工程中导入 Unity 工程的 unityLibrary 模块。 在 Android Studio 中,点击菜单栏 Fil…...

Python从入门到精通全套视频教程免费

概述 &#x1f4e2; 所有想学Python的小伙伴看过来&#xff01;作为深耕编程领域的技术分享者&#xff0c;最新整理了一份Python从0到1的视频教程。 &#x1f4a1;亮点 ✅ 保姆级系统路线&#xff1a;从环境搭建、语法精讲&#xff0c;到爬虫/数据分析/AI/Web全栈开发&#…...

关于Spring MVC中@RequestMapping注解的详细解析,涵盖其核心功能、属性、使用场景及最佳实践

以下是关于Spring MVC中RequestMapping注解的详细解析&#xff0c;涵盖其核心功能、属性、使用场景及最佳实践&#xff1a; 1. 基础概念 RequestMapping是Spring MVC的核心注解&#xff0c;用于将HTTP请求映射到控制器&#xff08;Controller&#xff09;的方法上。它支持类级…...

蓝桥杯:对字符串处理常用知识笔记

一、前面四个是计算带有空格字符串的的长度计算 C语言代码 #include<string.h> #include<stdio.h> int main() { char s[105]; gets(s); printf("%d", strlen(s)); return 0; } 算法2 C 代码&#xff08;常用&#xff09; #include <iostream> #in…...

实现一个 Markdown 编辑器组件:Vue 3 + Vite + Highlight.js

文章目录 一、项目背景与需求分析二、搭建基础项目1. 初始化 Vue 3 项目2. 安装依赖 三、实现 Markdown 编辑器组件1. 创建 Markdown 编辑器组件2. 组件说明 四、优化与拓展1. 自动保存功能2. 文件上传功能 五、总结 一、项目背景与需求分析 在现代前端开发中&#xff0c;Mark…...

【回眸】Linux 内核 (十四)进程间通讯 之 信号量

前言 信号量概念 信号量常用API 1.创建/获取一个信号量 2.改变信号量的值 3. 控制信号量 信号量函数调用 运行结果展示 前言 上一篇文章介绍的共享内存有局限性,如:同步与互斥问题、内存管理复杂性问题、数据结构限制问题、可移植性差问题、调试困难问题。本篇博文介…...

Redis的used_memory_peak_perc和used_memory_dataset_perc超过90%会怎么样

当Redis的used_memory_peak_perc&#xff08;当前内存占历史峰值的百分比&#xff09;和used_memory_dataset_perc&#xff08;数据集内存占比&#xff09;均超过90%时&#xff0c;可能引发以下问题及风险&#xff1a; 一、used_memory_peak_perc > 90% 的影响 内存交换风险…...

帆软fvs文件中某表格新增数据来声提醒

1.上传音频文件到帆软安装目录的指定环境 准备一个音频文件&#xff08;如 mp3 格式&#xff09;&#xff0c;并将其放置在合适的目录。 例如&#xff1a;%FR_HOME%\webapps\webroot\help 2.点击 FVS 模板左上角「模板>页面加载结束事件」&#xff0c;输入以下 JavaScript …...

从零用java实现 小红书 springboot vue uniapp (11)集成AI聊天机器人

前言 移动端演示 http://8.146.211.120:8081/#/ 管理端演示 http://8.146.211.120:8088/#/ 项目整体介绍及演示 前面的文章我们主要完成了基础模块的开发 这次我们跟一下热点 创建AI聊天机器人 并嵌入到我们的uniapp中 首先需要了解dify我已经完成了搭建win10 VMware安装ubuntu…...

Redis中AOF的实现方式和AOF重写

一、AOF 的实现方式 核心原理 AOF 通过将写操作命令以追加方式记录到日志文件中&#xff0c;重启时通过重放命令恢复数据。与 RDB 的快照机制不同&#xff0c;AOF 是增量记录&#xff0c;更适用于数据一致性要求较高的场景。写入流程 命令执行&#xff1a;客户端发送写命令&am…...

深入理解 React useLayoutEffect:精准掌控 DOM 更新时机

一、useLayoutEffect 的核心定位 1.1 与 useEffect 的关键差异 特性useEffectuseLayoutEffect执行时机浏览器绘制后异步执行DOM 更新后、绘制前同步执行视觉影响可能产生布局闪烁避免布局抖动性能影响对渲染阻塞较小可能阻塞浏览器渲染适用场景数据获取、事件订阅等DOM 测量、…...

Spring Boot 3.x 中 WebClient 全面详解及示例

Spring Boot 3.x 中 WebClient 全面详解及示例 1. WebClient 简介 定义&#xff1a;Spring 5 引入的响应式 HTTP 客户端&#xff0c;用于替代 RestTemplate&#xff08;已弃用&#xff09;&#xff0c;支持异步非阻塞的 HTTP 请求。核心特性&#xff1a; 支持所有 HTTP 方法&a…...

Vue3+Vite+TypeScript+Element Plus开发-06.Header响应式菜单缩展

系列文档目录 Vue3+Vite+TypeScript安装 Element Plus安装与配置 主页设计与router配置 静态菜单设计 Pinia引入 Header响应式菜单缩展 Mockjs引用与Axios封装 登录设计 登录成功跳转主页 多用户动态加载菜单 Pinia持久化 动态路由-配置 文章目录 目录 系列文档…...

深入解析原生鸿蒙中的 RN 日志系统:从入门到精通!

全文目录&#xff1a; 开篇语&#x1f4d6; 目录&#x1f3af; 前言&#xff1a;鸿蒙日志系统究竟有多重要&#xff1f;&#x1f6e0;️ 鸿蒙 RN 日志系统的基础结构&#x1f4dc; 1. 日志的作用⚙️ 2. 日志分类 &#x1f527; 如何在鸿蒙 RN 中使用日志系统&#x1f58b;️ 1…...

下一代AI App架构:前端生成,后端消失

过去十年&#xff0c;Web 和 App 的开发范式基本稳定&#xff1a;前端负责交互体验&#xff0c;后端负责业务逻辑和数据管理。即使是“无服务架构”也只是将后端“拆散”而非“消失”。 但随着 AI 原生应用的兴起&#xff0c;特别是 大模型本地化、小模型部署、WebAssembly、L…...

$_POST 超级全局变量

$_POST 是一个超级全局变量&#xff0c;在 PHP 中用于收集通过 HTTP POST 方法发送到服务器的数据。与 $_GET 不同&#xff0c;$_POST 允许发送大量数据&#xff0c;且数据不会显示在 URL 中&#xff0c;因此更适用于提交敏感信息&#xff0c;如用户登录信息、表单数据等。 使…...

开发一个环保回收小程序需要哪些功能?环保回收小程序

废品分类展示与识别 详细分类列表&#xff1a;清晰展示常见废品类型&#xff0c;如废纸&#xff08;报纸、书本纸、包装纸等&#xff09;、塑料&#xff08;塑料瓶、塑料容器、塑料薄膜等&#xff09;、金属&#xff08;易拉罐、铁制品、铜制品等&#xff09;、玻璃&#xff0…...

Debezium嵌入式连接postgresql封装服务

文章目录 1.项目结构&#xff1a;2.依赖&#xff1a;3.application.properties4.DebeziumConnectorConfig类5.TableEnum类6.TableHandler接口&#xff08;表处理抽象&#xff09;7.DefaultTableHandler默认实现类8.UserTableHandler处理类9.TableHandlerFactory工厂10.Debezium…...

Mixed Content: The page at https://xxx was loaded over HTTPS

一、核心原因分析 Mixed Content 警告是由于 HTTPS 页面中引用了 HTTP 协议的资源(如脚本、图片、iframe 等),导致浏览器因安全策略阻止加载这些非加密内容。HTTP 资源可能被中间人攻击篡改,破坏 HTTPS 页面的整体安全性。 二、推荐解决方案 1. 强制资源升级为 HTTPS •…...

深度学习、图像算法学习记录

深度学习加速 综述文档&#xff1a; https://chenzomi12.github.io/02Hardware01Foundation/02ArchSlim.html winograd: https://zhuanlan.zhihu.com/p/260109670 ncnn 1.修改模型结构&#xff0c;优化模型内存访问次数&#xff0c;加速。 VGG 和 InceptionNet &#xff1a; …...