Vue3实战三、Axios封装结合mock数据、Vite跨域及环境变量配置

目录

  • Axios封装、调用mock接口、Vite跨域及环境变量配置
    • 封装Axios对象调用mock接口数据
      • 第一步、安装axios,处理一部请求
      • 第二步、创建`request.ts`文件
      • 第三步、本地模拟mock数据接口
      • 第四步、测试axios+mock接口是否可以调用
      • 第五步、自行扩展 axios 返回的数据类型 axios.d.ts
    • 跨域解决
      • 什么是跨域
      • 跨域示例
      • 跨域解决
      • 跨域实操
    • Vite配置环境变量及模式
      • Vite 配置环境变量
      • Vite配置环境模式
    • 重构代理配置
    • 完结~

Axios封装、调用mock接口、Vite跨域及环境变量配置

封装Axios对象调用mock接口数据

因为项目中有很多接口要通过Axios发送异步请求,所以需要封装一个axios对象,自己封装的Axios后面可以时候axios中提供的拦截器,参考官方文档

第一步、安装axios,处理一部请求

npm install axios

Axios封装、Vite跨域及环境变量配置

第二步、创建request.ts文件

src 目录下创建utils目录,然后 utils 目录下创建 request.ts 文件

import axios from 'axios';
import type { AxiosInstance } from 'axios';
import { ElMessage } from 'element-plus';
// 手动创建一个 axios 对象, 参考: https://github.com/axios/axios#creating-an-instance
const request: AxiosInstance = axios.create({//baseURL: 'https://mock.xxx.com/mock/64fa8039e70b8004a69ea036/hsk-admin',// 根据不同环境设置 baseURL, 最终发送请求时的URL为: baseURL + 发送请求时写URL ,// 比如: `baseURL: '/dev-api'` ,当请求 get('/test'), 最终发送请求是: /dev-api/test// baseURL: '/dev-api',// 获取项目根目录下 .env.xxxx 文件中的环境变量值baseURL: import.meta.env.VITE_APP_BASE_API,timeout: 20000, // 请求超时的毫秒数,请求时间超过指定值,则请求会被中断
});
// 请求拦截器
request.interceptors.request.use(config => {// 在此处可向请求头加上认证tokenreturn config;
}, error => {// 出现异常, catch可捕获到return Promise.reject(error);
})
// 响应拦截器
request.interceptors.response.use(response => {// console.log('响应拦截器', response);const res = response.data;// 20000 正常响应,返回响应结果给调用方if (res.code === 20000) {return res;}// 非正常响应弹出错误信息,ElMessage.error(res.message);return Promise.reject(res);
}, error => {// 处理响应错误const { message, response } = error;if (message.indexOf('timeout') != -1) {ElMessage.error('网络超时!');} else if (message == 'Network Error') {ElMessage.error('网络连接错误!');} else {if (response.data) ElMessage.error(response.statusText);else ElMessage.error('接口路径找不到');}return Promise.reject(error);
});
export default request; // 导出 axios 对象

第三步、本地模拟mock数据接口

前后端分离开发过程中,后端数据接口还没有写出来,前端可以使用mock模拟假数据进行先一步页面的开发,使用mockjs模拟后端接口,可随机生成所需要的数据,模拟对数据的增删查改,mock支持丰富的数据类型,支持生成随机的文本数字布尔值日期邮箱链接图片颜色等,拦截Ajax请求不需要修改既有代码可以拦截,返回模拟的响应数据。

项目中使用mockjs的时候,首先确保安装了axiosmock,上面第一步的时候已经安装了axios数据,现在开始进行安装mock

npm install -D mockjs

Axios封装、Vite跨域及环境变量配置
在项目的src文件夹下新建一个文件夹用来存放mock模拟的数据,一般我们放在将mock模拟的数据( /src/mock/index.js)这个文件中,这里以此为例。

//这里是我使用本地的服务器商品接口地址模拟的数据
import { mock } from 'mockjs'
let data = mock({"code": 20000,"message": "查询成功","data": [{ "name": "小梦", "age": 18 },{ "name": "涛姐", "age": 32 },{ "name": "林志玲", "age": 48 }]
})
mock(/test/, 'get', () => {return data
})

Axios封装结合mock数据、Vite跨域及环境变量配置
模拟完数据后,在入口主文件 main.js 中引入这个模拟数据的文件

import "./mock/index.js"

Axios封装结合mock数据、Vite跨域及环境变量配置

第四步、测试axios+mock接口是否可以调用

src/ 下创建 /api/test.ts 目录和文件, 调用接口代码如下:

import request from "@/utils/request";
export function test1() {// 测试1: 调用 get 方式发送get请求request.get("/test").then(response => {console.log("get1", response);}).catch(error => {console.log('error', error);});
}export function test2() {// 测试2, 使用对象形式传入请求配置,如 请求url, method,paramrequest({url: `/test`,method: "GET"}).then(response => {console.log("get2", response);}).catch(error => {console.log(error);});
}

Axios封装结合mock数据、Vite跨域及环境变量配置
app.vue页面引入接口并调用:

<template><div><el-icon><ele-Search /></el-icon><SvgIcon name="ele-Search"></SvgIcon><el-button type="primary">Primary</el-button></div>
</template>
<script lang="ts" setup>
// 导入 test.ts,
import { test1, test2 } from "../src/api/test.ts";
// 调用方法发送请求
test1();
test2();
</script>
<style lang="scss">
// 编写 scss 代码
</style>

效果:
在这里插入图片描述
测试三、通过 api 方法返回请求的 Promise 对象,然后在调用方通过then 获取响应数据,api\test.ts 新增如下代码:

import request from "@/utils/request";
// 返回 Promise
export function getList() {const req = request({url: `/test`,method: "GET"});// console.log(req) // Promisereturn req;
}

App.vue 中导入 test.ts

<script setup lang='ts'>
// 导入 test.ts,调用方法发送请求
import { getList } from "@/api/test";
import { onMounted } from "vue";
onMounted(() => {loadData();loadData2();
});
function loadData() {getList().then((response: any) => {console.log("loadData", response);}).catch((error: Error) => {console.log(error);});
}
// 使用 async+await
async function loadData2() {const response = await getList();console.log("loadData2", response);
}
</script>

Axios封装结合mock数据、Vite跨域及环境变量配置
后面数据访问都采用测试三这种方式。

第五步、自行扩展 axios 返回的数据类型 axios.d.ts

  1. 使用axios发送请求接口后,axios生命的响应对象AxiosResponse中的属性并不是我们想要的,我们需要自行扩展为我们需要相应的数据类型。

    /* eslint-disable */
    import * as axios from 'axios';
    // 自行扩展 axios 返回的数据类型
    declare module 'axios' {export interface AxiosResponse<T = any> {code: number;message: string;data: T;}
    }
    

    Axios封装结合mock数据、Vite跨域及环境变量配置
    declare 定义的接口类型,在 SFCts 文件中不需要导入,相当于全局接口,直接引用接口类型。但是要告知 ts 文件在哪里

  2. 自动加载 *.d.ts文件,修改 tsconfig.app.json (旧版本在 tsconfig.json 中)文件的 includes 选项值:追加 "src/**/*.d.ts"

{"extends": "@vue/tsconfig/tsconfig.dom.json","include": ["env.d.ts", "src/**/*", "src/**/*.vue", "src/**/*.d.ts"],"exclude": ["src/**/__tests__/*"],"compilerOptions": {"composite": true,"baseUrl": ".","paths": {"@/*": ["./src/*"]}}
}

Axios封装结合mock数据、Vite跨域及环境变量配置
注意:添加后,重启编辑器VsCode,不然可能无法识别到*.d.ts文件

跨域解决

什么是跨域

前后端分离时,前端和后端API服务器可能不在同一台主机上面,就存在跨域问题,浏览器限制了跨域访问,违反了同源策略【协议,域名,端口】都要相同,其中一个不同都会产生跨域。

跨域示例

  • 前端部署在http://127.0.0.1:8888/即本地ip端口8888上面
  • 后端API部署在http://127.0.0.1:9999/即本地ip端口999上面

他们的IP一样,但是端口不一样就会存在跨域问题。
Axios封装结合mock数据、Vite跨域及环境变量配置

跨域解决

【跨域解决参考文档入口】

  • 通过代理请求的方式解决,将 API 请求通过代理服务器请求到 API 服务器。
  • 开发环境中,在 vite.config.ts 文件中使用 server.proxy 选项进行代理配置。
  • 生产环境,可采用 nginx代理 解决跨域问题。

跨域实操

  1. vite.config.ts 文件中使用 server.proxy 选项进行代理配置。
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({// 开发服务器选项,参考:https://cn.vitejs.dev/config/server-options.html#server-hostserver: {open: true, //启动服务时自动打开浏览器访问port: 8888, //端口号, 如果端口号被占用,会自动提升1proxy: { // ++++++++++++++++++ 解决跨域问题'/dev-api': { // 匹配 /dev-api 开头的请求,// 目标服务器, 代理访问到https://mock.mengxuegu.com/mock/6621e5cbfaa39b4567596484/adminPowertarget: 'https://mock.mengxuegu.com/mock/6621e5cbfaa39b4567596484/adminPower',// 开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,// 这样服务端和服务端进行数据的交互就不会有跨域问题changeOrigin: true,// 将 /dev-api 替换为 '',也就是 /dev-api 会移除,// 如 /dev-api/test 代理到https://mock.mengxuegu.com/mock/6621e5cbfaa39b4567596484/adminPowerrewrite: (path) => path.replace(/^\/dev-api/, ''),},}},plugins: [vue(),],resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))}}
})
  1. src\utils\request.ts 中的 baseURL 修改:
    const request: AxiosInstance = axios.create({baseURL: '/dev-api',timeout: 20000, // 请求超时的毫秒数,请求时间超过指定值,则请求会被中断
    });
    Axios封装结合mock数据、Vite跨域及环境变量配置
  2. 测试:访问http://127.0.0.1:8888/,查看控制台响应了数据,说明代理成功
    Axios封装结合mock数据、Vite跨域及环境变量配置

Vite配置环境变量及模式

Vite 配置环境变量

环境分为testprodtest环境,他们请求的后台接口获取数据,不同环境的接口的URL不同,所以要为不同环境配置不同的接口URL,通过路径前缀进行匹配。

  1. 在根目录下创建.env.development.env.production文件,为了防止意外地讲一些环境变量泄漏到客户端,只有以VITE_为前缀的环境变量才会通过import.meta.env以字符串形式暴露给经过Vite处理的代码使用。

    如:

    • VITE_DEV_API=/dev-api可以通过 import.meta.env.VITE_DEV_API访问,返回/dev-api
    • WY_DEV_API=/dev-api不能通过 import.meta.env.WY_DEV_API访问,返回undefined
  2. .env.development 文件配置(注意开发和生产环境配置不要搞反了)VITE_APP_SERVICE_URL 值更改为你自已配置的 项目后端的 接口服务地址。

    # 使用 VITE_ 开头的变量会被 vite 暴露出来
    # 定义请求的基础URL, 方便跨域请求时使用
    VITE_APP_BASE_API=/dev-api
    # 接口服务地址
    VITE_APP_SERVICE_URL= https://www.****.com/
    
  3. .env.production 文件配置

    # 使用 VITE_ 开头的变量会被 vite 暴露出来
    # 定义请求的基础URL, 方便跨域请求时使用
    VITE_APP_BASE_API=/pro-api
    # 接口服务地址
    VITE_APP_SERVICE_URL= https://www.****.com/
    
  4. 测试是否配置成功,在 request.ts 中添加以下代码,看下浏览器控制台是否会输出,在项目任意模块文件中,都可以使用 通过 import.meta.env.VITE_APP_BASE_API 获取值:

    import axios from 'axios';
    import type { AxiosInstance } from 'axios';
    import { ElMessage } from 'element-plus';
    console.log(import.meta.env.VITE_APP_BASE_API)
    const request: AxiosInstance = axios.create({baseURL: '/dev-api',timeout: 20000, // 请求超时的毫秒数,请求时间超过指定值,则请求会被中断
    });
    

    Axios封装结合mock数据、Vite跨域及环境变量配置

Vite配置环境模式

默认情况下,开发服务器 ( dev 命令) 运行在 development (开发) 模式,而 build 命令则运行在 production(生产) 模式。
查看package.json ,当执行 vite build 时,它会自动加载 .env.production 中可能存在的环境变量:

VITE_APP_BASE_API=/pro-api

utils/request.ts 中可以使用import.meta.env.VITE_APP_BASE_API 获取引用。在某些情况下,若想在 vite build 时运行不同的模式来渲染不同的标题,你可以通过传递 --mode 选项标志来覆盖命令使用的默认模式。

例如,如果你想在 production(生产)模式下构建应用:

  1. 项目根目录下新建一个 .env.production文件:
    Axios封装结合mock数据、Vite跨域及环境变量配置

  2. package.json 中添加一个prod选项运行 vite --mode production命令
    Axios封装结合mock数据、Vite跨域及环境变量配置

  3. 启动prod环境查看console.log(import.meta.env.VITE_APP_BASE_API) 打印结果:
    在这里插入图片描述
    Axios封装结合mock数据、Vite跨域及环境变量配置

重构代理配置

重构vite.config中的server.proxy代理配置,在vite.config.ts中无法通过import.meta.env.xxx获取到VITE_环境变量,解决此问题需要用到vite中提供的loadEnv方法来读取环境变量。

import { defineConfig, loadEnv } from 'vite'
// mode:获取 --mode 指定的模式,process.cwd()项目根目录,下面 `env` 相当于 `import.meta.env`
const env = loadEnv(mode, process.cwd());
  1. 重构vite.config中的server.proxy代理配置
    import { fileURLToPath, URL } from 'node:url'
    // 1. 导入 loadEnv
    import { defineConfig, loadEnv } from 'vite'
    import vue from '@vitejs/plugin-vue'
    // 2. 向 defineConfig 传递对象改为传递方法,并返回配置对象
    export default defineConfig(({ mode }) => {// mode:获取 --mode 指定的模式,process.cwd()项目根目录,下面 `env` 相当于 `import.meta.env`const env = loadEnv(mode, process.cwd());return {// 开发服务器选项server: {open: true, //启动服务时自动打开浏览器访问port: 8888, //端口号, 如果端口号被占用,会自动提升1proxy: {// '/dev-api': { // 匹配 /dev-api 开头的请求,[env.VITE_APP_BASE_API]: { // 引用变量作为key时,要加中括号[]// 目标服务器target: env.VITE_APP_SERVICE_URL,// 开启代理changeOrigin: true,rewrite: path => path.replace(new RegExp(`^${env.VITE_APP_BASE_API}/`), '')},}},plugins: [vue(),],resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))}}}
    });
    
  2. 修改 utils/request.ts 文件配置: baseURL: import.meta.env.VITE_APP_BASE_API
    import axios from 'axios';
    import type { AxiosInstance } from 'axios';
    import { ElMessage } from 'element-plus';
    console.log(import.meta.env.VITE_APP_BASE_API)
    const request: AxiosInstance = axios.create({baseURL: import.meta.env.VITE_APP_BASE_API,timeout: 20000, // 请求超时的毫秒数,请求时间超过指定值,则请求会被中断
    });
    
    Axios封装结合mock数据、Vite跨域及环境变量配置
  3. 重启看一下效果,接口是否调用到
    Axios封装结合mock数据、Vite跨域及环境变量配置

完结~

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

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

相关文章

Linux如何删除文件名包含无效编码字符文件

在Linux中&#xff0c;文件名包含无效编码字符或特殊不可见字符时&#xff0c;可能导致此文件无法通过常规方式选中或删除&#xff0c;可以通过下面方法处理 1、确认文件名问题 检查终端编码环境 echo $LANG # 默认应为 UTF-8&#xff08;如 en_US.UTF-8&#xff09; 查看…

Completablefuture的底层原理是什么

参考面试回答&#xff1a; 个人理解 CompletableFuture 是 Java 8 引入的一个类、它可以让我们在多线程环境中更加容易地处理异步任务。CompletableFuture 的底层原理是基于一个名为 FutureTask 的机制、结合了 监听器模式 和 等待-通知机制 来处理异步计算。 1.首先就是Com…

C/C++ 调用约定:深入理解栈与平栈

前言 在编程中&#xff0c;理解函数调用约定和栈的机制对于编写高效代码、调试程序以及进行逆向工程至关重要。本文将深入探讨 C 和 C 的调用约定&#xff0c;以及栈与平栈的相关知识。 C 调用约定 在 C 语言中&#xff0c;默认的调用约定是 cdecl。cdecl 调用约定的特点如下&…

xv6-labs-2024 lab1

lab-1 注&#xff1a;实验环境在我的汇编随手记的末尾部分有搭建教程。 0.前置 第零章 xv6为我们提供了多种系统调用&#xff0c;其中&#xff0c;exec将从某个文件里读取内存镜像(这确实是一个好的说法)&#xff0c;并且将其替换到调用它的内存空间&#xff0c;也就是这个…

属性修改器 (AttributeModifier)

主页面设置组件 import { MyButtonModifier } from ../datastore/MyButtonModifier;Entry ComponentV2 struct MainPage {// 支持用状态装饰器修饰&#xff0c;行为和普通的对象一致Local modifier: MyButtonModifier new MyButtonModifier();build() {Column() {Button(&quo…

【 <二> 丹方改良:Spring 时代的 JavaWeb】之 Spring Boot 中的监控:使用 Actuator 实现健康检查

<前文回顾> 点击此处查看 合集 https://blog.csdn.net/foyodesigner/category_12907601.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12907601&sharereferPC&sharesourceFoyoDesigner&sharefromfrom_link <今日更新> 一、引子&…

类和对象(下篇)(详解)

【本节目标】 1. 再谈构造函数 2. Static成员 3. 友元 4. 内部类 5. 再次理解封装 1. 再谈构造函数 1.1 构造函数体赋值 在创建对象时&#xff0c;编译器通过调用构造函数&#xff0c;给对象中各个成员变量一个合适的初始值。 #include <iostream> using name…

高精度算法

高精度加法 输入两个数&#xff0c;输出他们的和&#xff08;高精度&#xff09; 输入样例 111111111111111111111111111111 222222222222222222222222222222 输出样例 333333333333333333333333333333 #include <bits/stdc.h> using namespace std;string a,b; in…

Linux开发中注意哪些操作系统安全

在 Linux 开发中&#xff0c;确保操作系统的安全至关重要。以下是一些需要注意的方面&#xff1a; 用户管理与权限控制 合理设置用户权限&#xff1a;为不同的用户和用户组分配适当的权限&#xff0c;遵循最小权限原则。避免给普通用户过多的权限&#xff0c;以免他们误操作或…

x64dbg调试python解释器

可以先写个input()这会让dbg中断在ntdll模块中&#xff0c;查看调用堆栈在系统调用结束后的打断点 然后直接断到PyObject_Vectorcall函数

✅ Ultralytics YOLO验证(Val)时自动输出COCO指标(AP):2025最新配置与代码详解 (小白友好 + B站视频)

✅ YOLO获取COCO指标(3)&#xff1a;验证(Val) 启用 COCO API 评估&#xff08;自动输出AP指标&#xff09;| 发论文必看&#xff01; | Ultralytics | 小白友好 文章目录 一、问题定位二、原理分析三、解决方案与实践案例步骤 1: 触发 COCO JSON 保存步骤 2: 确保 self.is_coc…

【嵌入式学习3】基于python的tcp客户端、服务器

目录 1、tcp客户端 2、tcp服务器 3、服务器多次连接客户端、多次接收信息 1、tcp客户端 """ tcp:客户端 1. 导入socket模块 2. 创建socket套接字 3. 建立tcp连接(和服务端建立连接) 4. 开始发送数据(到服务端) 5. 关闭套接字 """ import soc…

Linux: network: 两台直连的主机业务不通

前提环境,有一个产品的设定是两个主机之间必须是拿网线直连。但是设备管理者可能误将设置配错,不是直连。 最近遇到一个问题,说一个主机发的包,没有到对端,一开始怀疑设定的bond设备的问题,检查了bond的设置状态,发现没有问题,就感觉非常的奇怪。后来就开始怀疑两个主机…

COMSOL固体力学接触

目录 一、接触非线性及接触面积计算 一、接触非线性及接触面积计算 COMSOL接触非线性及接触面积计算_哔哩哔哩_bilibili 形成联合体&#xff0c;在定义处右键选择“建立接触对” 位移dz使用参数化扫描。 接触选择定义中设置的接触对&#xff0c;选择罚函数&#xff0c;摩擦设置…

22.OpenCV轮廓匹配原理介绍与使用

OpenCV轮廓匹配原理介绍与使用 1. 轮廓匹配的基本概念 轮廓匹配&#xff08;Contour Matching&#xff09;是计算机视觉中的一种重要方法&#xff0c;主要用于比较两个轮廓的相似性。它广泛应用于目标识别、形状分析、手势识别等领域。 在 OpenCV 中&#xff0c;轮廓匹配主要…

oracle 快速创建表结构

在 Oracle 中快速创建表结构&#xff08;仅复制表结构&#xff0c;不复制数据&#xff09;可以通过以下方法实现&#xff0c;适用于需要快速复制表定义或生成空表的场景 1. 使用 CREATE TABLE AS SELECT (CTAS) 方法 -- 复制源表的全部列和数据类型&#xff0c;但不复制数据 C…

若依原理笔记

代码生成器 源码分析 查询数据库列表 导入表结构 生成代码 修改generator.yml配置文件 代码生成器增强 Velocity模版引擎 基础语法-变量 Lombok集成 E:\javaProject\dkd-parent\dkd-generator\src\main\resources\vm\java\domain.java.vm package ${packageName}.domain;#fo…

Ansible的使用

##### Ansible使用环境 - 控制节点 - 安装Ansible软件 - Python环境支持&#xff1a;Python>2.6 - 必要的模块&#xff1a;如PyYAML等 - 被控节点 - 启用SSH服务 - 允许控制节点登录&#xff0c;通常设置免密登录 - Python环境支持 http://www.ansible.com/ …

C++ 提高编程:模板与 STL 深度剖析

摘要&#xff1a;本文深入探讨 C 提高编程中的模板编程与标准模板库&#xff08;STL&#xff09;相关内容。详细阐述模板编程中函数模板和类模板的概念、语法、特性及应用案例&#xff1b;对 STL 的诞生背景、基本概念、六大组件进行剖析&#xff0c;并对常用容器、函数对象、常…

C++(类模板的运用)

使用vector实现一个简单的本地注册登录系统 注册&#xff1a;将账号密码存入vector里面&#xff0c;注意防重复判断 登录&#xff1a;判断登录的账号密码是否正确 #include <iostream> #include <vector> #include <fstream> #include <sstream> usi…