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

news2025/4/8 10:41:25

目录

  • 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 => {
  // 在此处可向请求头加上认证token
  return 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,param
  request({
    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) // Promise
  return 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-host
  server: {
    open: true, //启动服务时自动打开浏览器访问
    port: 8888, //端口号, 如果端口号被占用,会自动提升1
    proxy: { // ++++++++++++++++++ 解决跨域问题
      '/dev-api': { // 匹配 /dev-api 开头的请求,
        // 目标服务器, 代理访问到https://mock.mengxuegu.com/mock/6621e5cbfaa39b4567596484/adminPower
        target: 'https://mock.mengxuegu.com/mock/6621e5cbfaa39b4567596484/adminPower',
        // 开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,
        // 这样服务端和服务端进行数据的交互就不会有跨域问题
        changeOrigin: true,
        // 将 /dev-api 替换为 '',也就是 /dev-api 会移除,
        // 如 /dev-api/test 代理到https://mock.mengxuegu.com/mock/6621e5cbfaa39b4567596484/adminPower
        rewrite: (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, //端口号, 如果端口号被占用,会自动提升1
          proxy: {
            // '/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.coloradmin.cn/o/2330415.html

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

相关文章

机器学习(神经网络基础篇)——个人理解篇5(梯度下降中遇到的问题)

在神经网络训练中&#xff0c;计算参数的梯度是关键步骤。numerical_gradient 方法旨在通过数值微分&#xff08;中心差分法&#xff09;计算损失函数对网络参数的梯度。然而&#xff0c;该方法的实现存在一个关键问题&#xff0c;导致梯度计算错误。 1、错误代码示例&#xf…

【Linux】虚拟机设置静态IP

主播我今天下午学了几节微服务课&#xff0c;上课的时候&#xff0c;直接把手机拿走了去上课&#xff08;电脑连的我手机的热点&#xff09;&#xff0c;虚拟机没关&#xff0c;晚上主播我回来继续学&#xff0c;电脑连上热点之后&#xff0c;发现虚拟机连接不上了&#xff0c;…

职坐标解析自动驾驶技术发展新趋势

内容概要 作为智能交通革命的核心驱动力&#xff0c;自动驾驶技术正以惊人的速度重塑出行生态。2023年&#xff0c;行业在多传感器融合与AI算法优化两大领域实现突破性进展&#xff1a;激光雷达、摄像头与毫米波雷达的协同精度提升至厘米级&#xff0c;而深度学习模型的实时决…

局域网:电脑或移动设备作为主机实现局域网访问

电脑作为主机 1. 启用电脑的网络发现、SMB功能 2. 将访问设备开启WIFI或热点&#xff0c;用此电脑连接&#xff1b;或多台设备连接到同一WIFI 3. 此电脑打开命令行窗口&#xff0c;查看电脑本地的IP地址 Win系统&#xff1a;输入"ipconfig"&#xff0c;回车后如图 4.…

小型园区组网图

1. 在小型园区中&#xff0c;S5735-L-V2通常部署在网络的接入层&#xff0c;S8700-4通常部署在网络的核心&#xff0c;出口路由器一般选用AR系列路由器。 2. 接入交换机与核心交换机通过Eth-Trunk组网保证可靠性。 3. 每个部门业务划分到一个VLAN中&#xff0c;部门间的业务在C…

数据分享:汽车测评数据

说明&#xff1a;如需数据可以直接到文章最后关注获取。 1.数据背景 Car Evaluation汽车测评数据集是一个经典的机器学习数据集&#xff0c;最初由 Marko Bohanec 和 Blaz Zupan 创建&#xff0c;并在 1997 年发表于论文 "Classifier learning from examples: Common …

批量将 txt/html/json/xml/csv 等文本拆分成多个文件

我们的文本文件太大的时候&#xff0c;我们通常需要对文本文件进行拆分&#xff0c;比如按多少行一个文件将一个大的文本文件拆分成多个小的文本文件。这样我们在打开或者传输的时候都比较方便。今天就给大家介绍一种同时对多个文本文件进行批量拆分的方法&#xff0c;可以快速…

Vue3 路由权限管理:基于角色的路由生成与访问控制

Vue3 路由权限管理&#xff1a;基于角色的路由生成与访问控制 一、核心概念 1.1 大致流程思路&#xff1a; 用户在登录完成的时候&#xff0c;后端给出一个此登录用户对应的角色名字&#xff0c;此时可以将这个用户的角色存起来(vuex/pinia)中&#xff0c;在设置路由时的met…

忘记mysql的root用户密码(已解决)

1、打开数据库可视化界面&#xff08;比如MySQL workbench&#xff09; 2、执行select host,user,authentication_string from mysql.user; 3、把‘authentication_string’下面的字段 复制到MD5在线解密网页中&#xff08;比如md5在线解密&#xff09;

ubuntu 20.04 编译和运行SC-LeGo-LOAM

1.搭建文件目录和clone代码 mkdir -p SC-LeGo-LOAM/src cd SC-LeGo-LOAM/src git clone https://github.com/AbangLZU/SC-LeGO-LOAM.git cd .. 2.修改代码 需要注意的是原作者使用的是Ouster OS-64雷达&#xff0c;需要更改utility.h文件中适配自己的雷达类型&#xff0c;而…

CentOS 7安装hyperscan

0x00 前言 HyperScan是一款由Intel开发的高性能正则表达式匹配库&#xff0c;专为需要快速处理大量数据流的应用场景而设计。它支持多平台运行&#xff0c;包括Linux、Windows和macOS等操作系统&#xff0c;并针对x86架构进行了优化&#xff0c;以提供卓越的性能表现。HyperSc…

UE5 Simulation Stage

首先将Grid2D创建出来&#xff0c;然后设置值&#xff0c;Grid2D类似于在Niagara系统中的RenderTarget2D&#xff0c;可以进行绘制&#xff0c;那么设置大小为512 * 512 开启Niagara粒子中的Simulation Stage 然后开始编写我们的自定义模块 模块很简单&#xff0c;TS就是Textur…

Swift 解 LeetCode 250:搞懂同值子树,用递归写出权限系统检查器

文章目录 前言问题描述简单说&#xff1a;痛点分析&#xff1a;到底难在哪&#xff1f;1. 子树的概念搞不清楚2. 要不要“递归”&#xff1f;递归从哪开始&#xff1f;3. 怎么“边遍历边判断”&#xff1f;这套路不熟 后序遍历 全局计数器遍历过程解释一下&#xff1a;和实际场…

增益调度控制 —— 理论、案例与交互式 GUI 实现

目录 增益调度控制 —— 理论、案例与交互式 GUI 实现一、引言二、增益调度控制的基本原理三、数学模型与公式推导四、增益调度控制的优势与局限4.1 优势4.2 局限五、典型案例分析5.1 案例一:航空飞行控制中的增益调度5.2 案例二:发动机推力控制中的增益调度5.3 案例三:化工…

关于OEC/OEC-turbo刷机问题的一些解决方法(2)——可能是终极解决方法了

前面写了两篇关于OEC/OEC-turbo刷机问题的文章了&#xff0c;从刷机过程、刷机中遇到的问题&#xff0c;以及遇到最多但始终无法有效解决的下载boot失败的问题的剖析&#xff0c;最近确实也做了一些工作&#xff0c;虽然没有最终解决&#xff0c;但也算是这系列文章里面阶段性的…

瓦片数据合并方法

影像数据 假如有两份影像数据 1.全球底层影像0-5级别如下&#xff1a; 2.局部高清影像数据级别9-14如下&#xff1a; 合并方法 将9-14文件夹复制到全球底层0-5的目录下 如下&#xff1a; 然后合并xml文件 使得Tileset设置到最高级&#xff08;包含所有级别&#xff09;&…

第16届蓝桥杯单片机模拟试题Ⅰ

试题 代码 sys.h #ifndef __SYS_H__ #define __SYS_H__#include <STC15F2K60S2.H> //onewire.c float getT(); //sys.c extern unsigned char UI; extern bit touch_mode; extern float jiaozhun; extern float canshu; extern float temper; void init74hc138(unsigned…

mac 卸载流氓软件安全助手

之前个人电脑在公司使用过一段时间&#xff0c;为了使用网线联网安装了公司指定的 联软上网助手&#xff0c;谁知安装容易卸载难&#xff0c;后来找运维来卸载&#xff0c;输入管理员密码后&#xff0c;也无反应&#xff0c;最后不了了之了&#xff0c;这个毒瘤软件长期在后台驻…

⭐算法OJ⭐滑动窗口最大值【双端队列(deque)】Sliding Window Maximum

文章目录 双端队列(deque)详解基本特性常用操作1. 构造和初始化2. 元素访问3. 修改操作4. 容量操作 性能特点时间复杂度&#xff1a;空间复杂度&#xff1a; 滑动窗口最大值题目描述方法思路解决代码 双端队列(deque)详解 双端队列(deque&#xff0c;全称double-ended queue)是…

沧州铁狮子

又名“镇海吼”&#xff0c;是中国现存年代最久、形体最大的铸铁狮子&#xff0c;具有深厚的历史文化底蕴和独特的艺术价值。以下是关于沧州铁狮子的详细介绍&#xff1a; 历史背景 • 铸造年代&#xff1a;沧州铁狮子铸造于后周广顺三年&#xff08;953年&#xff09;&#…