配置环境变量
-
先创建这第三个文件 分别是 开发环境 生产环境 测试环境的配置 到时候就能取到里面的值
-
.env.development
-
VUE_APP_BASE_URL = http://localhost:3000/ VUE_APP_BASE_NAME = name
-
-
.env.production
-
VUE_APP_BASE_URL = http://localhost:3000/ VUE_APP_BASE_NAME = name
-
-
.env.test
-
VUE_APP_BASE_URL = http://localhost:3000/ VUE_APP_BASE_NAME = name
-
-
坑
- 如果使用的是 vite 那么 开头要改成 VITE_BASE_RUL 才能获取到其中的配置 可以自行打印一下
-
-
可以通过
console.log(import.meta.url)直接取 -
我这里重新配置了
- config.ts
-
let BASE_URL = '' const TIME_OUT = 10000 if (import.meta.env.MODE === 'development') { BASE_URL = 'http://123.207.32.32:8000/' } else if (import.meta.env.MODE === 'production') { BASE_URL = '' } else { BASE_URL = '' } export { BASE_URL, TIME_OUT } - 跟下面的 axios 一起封装使用
axios 安装
-
yarn add axios -S
封装
-
使用了 ts 进行类型约束
-
目录结构 request 文件夹下的的 axios 的二次封装 跟上面的环境变量一块的
-
request type.ts
-
import type { AxiosRequestConfig, AxiosResponse } from 'axios' // 定义传入的实例的类 export interface HYRequestInterceptors<T = AxiosResponse> { requestInterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig requestInterceptorCatch?: (error: any) => any responseInterceptor?: (res: T) => T responseInterceptorCatch?: (error: any) => any } export interface HYRequestConfig<T = AxiosResponse> extends AxiosRequestConfig { interceptors?: HYRequestInterceptors<T> showLoading?: boolean }
-
-
request index.ts
- 使用类进行封装 添加了 请求拦截 和响应拦截
- 并且拦截可以是全布实例的 或者每个实例传入 config 单独配置的
- 其中引入了 element 的过渡加载 不需要的可以自行删除相关代码
-
import axios from 'axios' import type { AxiosInstance } from 'axios' import type { HYRequestInterceptors, HYRequestConfig } from './type' // 引入加载过渡 import { ElLoading } from 'element-plus' // 加载动画显示隐藏 const DEAFULT_LOADING = true class HYRequest { // 属性 instance: AxiosInstance interceptors?: HYRequestInterceptors showLoading: boolean loading?: any // 构造函数 传入配置 constructor(config: HYRequestConfig) { // 创建axios实例 this.instance = axios.create(config) // 保存基本信息 this.showLoading = config.showLoading ?? DEAFULT_LOADING this.interceptors = config.interceptors // 使用拦截器 // 1.从config中取出的拦截器是对应的实例的拦截器 this.instance.interceptors.request.use( this.interceptors?.requestInterceptor, this.interceptors?.requestInterceptorCatch ) this.instance.interceptors.response.use( this.interceptors?.responseInterceptor, this.interceptors?.responseInterceptorCatch ) // 2.添加所有的实例都有的拦截器 this.instance.interceptors.request.use( (config) => { // 动画的显示和隐藏 if (this.showLoading) { this.loading = ElLoading.service({ lock: true, text: '正在请求数据....', background: 'rgba(0, 0, 0, 0.5)', }) } return config }, (err) => { return err } ) // 响应拦截器 this.instance.interceptors.response.use( (res) => { // 将loading移除 this.loading?.close() const data = res.data if (data.returnCode === '-1001') { console.log('请求失败~, 错误信息') } else { return data } }, (err) => { // 将loading移除 this.loading?.close() // 例子: 判断不同的HttpErrorCode显示不同的错误信息 if (err.response.status === 404) { console.log('404的错误~') } return err } ) } // 方法 request<T>(config: HYRequestConfig<T>): Promise<T> { return new Promise((resolve, reject) => { // 1.单个请求对请求config的处理 if (config.interceptors?.requestInterceptor) { config = config.interceptors.requestInterceptor(config) } // 2.判断是否需要显示loading if (config.showLoading === false) { this.showLoading = config.showLoading } this.instance .request<any, T>(config) .then((res) => { // 1.单个请求对数据的处理 if (config.interceptors?.responseInterceptor) { res = config.interceptors.responseInterceptor(res) } // 2.将showLoading设置true, 这样不会影响下一个请求 this.showLoading = DEAFULT_LOADING // 3.将结果resolve返回出去 resolve(res) }) .catch((err) => { // 将showLoading设置true, 这样不会影响下一个请求 this.showLoading = DEAFULT_LOADING reject(err) return err }) }) } // 封装四个请求 get<T>(config: HYRequestConfig<T>): Promise<T> { return this.request<T>({ ...config, method: 'GET' }) } post<T>(config: HYRequestConfig<T>): Promise<T> { return this.request<T>({ ...config, method: 'POST' }) } delete<T>(config: HYRequestConfig<T>): Promise<T> { return this.request<T>({ ...config, method: 'DELETE' }) } patch<T>(config: HYRequestConfig<T>): Promise<T> { return this.request<T>({ ...config, method: 'PATCH' }) } } // 默认暴露出定义的类 其他地方引入 并且使用就行了 export default HYRequest
-
service index.ts
-
// service统一出口 import HYRequest from './request' // 全局环境变量 import { BASE_URL, TIME_OUT } from './request/config' import localCache from '@/utils/cache' // 封装一个 实例 const hyRequest = new HYRequest({ // 属性 也就是基本配置 baseURL: BASE_URL, timeout: TIME_OUT, // 拦截器 interceptors: { requestInterceptor: (config: any) => { // 携带token的拦截 const token = localCache.getCache('token') if (token) { config.headers.Authorization = `Bearer ${token}` } return config }, requestInterceptorCatch: (err) => { return err }, responseInterceptor: (res) => { return res }, responseInterceptorCatch: (err) => { return err }, }, }) export default hyRequest
-
使用
-
以封装 login 作为例子
-
type.ts
-
// 输入数据的约束 export interface IAccount { name: string password: string } // 对登录返回数据的 约束 export interface ILoginResult { id: number name: string token: string } export interface IDataType<T = any> { code: number data: T }
-
-
login.ts
-
// 引入封装的实例对象 import hyRequest from '../index' // 引入定义的 类 import { IAccount, IDataType, ILoginResult } from './type' enum LoginAPI { AccountLogin = '/login', LoginUserInfo = '/users/', // 用法: /users/1 } // 登录方法 传入账号密码 发送 post 请求 export function accountLoginRequest(account: IAccount) { return hyRequest.post<IDataType<ILoginResult>>({ url: LoginAPI.AccountLogin, data: account, }) } export function requestUserInfoById(id: number) { return hyRequest.get<IDataType>({ url: LoginAPI.LoginUserInfo + id, showLoading: false, }) }
-
-
然后把这几个函数导出到登录模块中使用就行了 也可以在 vuex 中使用
-
再举一个实例
-
main.ts 下测试
-
import { createApp } from 'vue' import App from './App.vue' import ElementPlus from 'element-plus' import router from './router' import store from './store' // 引入封装的 axios import hyRequest from './service' const app = createApp(App) app.use(ElementPlus) app.use(router) app.use(store) app.mount('#app') // 环境变量 console.log(import.meta.env) // hyRequest .request({ url: '/home/multidata', method: 'GET', headers: {}, interceptors: { requestInterceptor: (config: any) => { console.log('单独请求的config') config.headers['token'] = '123' return config }, responseInterceptor: (res) => { console.log('单独响应的response') return res }, }, }) .then((res) => { console.log(res) })
-