這是我參與更文挑戰的第18天,活動詳情查看:更文挑戰前端
npm
: npm install axiosvue
yarn
: yarn add axiosreact
import { AxiosInstance, AxiosRequestConfig, AxiosPromise } from "axios"
/**
* 自定義擴展axios模塊
* @author 何小玍。
*/
declare module "axios" {
export interface AxiosRequestConfig {
/**
* @description 設置爲true,則會在請求過程當中顯示loading動畫,直到請求結束才消失
*/
loading?: boolean
isDialog?: boolean
}
export interface AxiosInstance {
<T = any>(config: AxiosRequestConfig): Promise<T>
request<T = any>(config: AxiosRequestConfig): Promise<T>
get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>
delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>
head<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>
post<T = any>(
url: string,
data?: any,
config?: AxiosRequestConfig
): Promise<T>
put<T = any>(
url: string,
data?: any,
config?: AxiosRequestConfig
): Promise<T>
patch<T = any>(
url: string,
data?: any,
config?: AxiosRequestConfig
): Promise<T>
}
}
複製代碼
src文件夾
下,建立utils文件夾
,放封裝文件request.js
/**
* @description [ axios 請求封裝]
*/
// import store from "@/store";
import axios, { AxiosResponse, AxiosRequestConfig } from "axios";
// import { Message, Modal } from 'view-design' // UI組件庫
import { Dialog, Toast } from "vant";
import router from "@/router";
// 根據環境不一樣引入不一樣api地址
import { config } from "@/config";
const service = axios.create({
baseURL: config.baseApi + "/api", // url = base url + request url
timeout: 5000,
withCredentials: false // send cookies when cross-domain requests
// headers: {
// // clear cors
// 'Cache-Control': 'no-cache',
// Pragma: 'no-cache'
// }
})
// Request interceptors
service.interceptors.request.use(
(config: AxiosRequestConfig) => {
// 加載動畫
if (config.loading) {
Toast.loading({
message: "加載中...",
forbidClick: true
});
}
// 在此處添加請求頭等,如添加 token
// if (store.state.token) {
// config.headers['Authorization'] = `Bearer ${store.state.token}`
// }
return config;
},
(error: any) => {
Promise.reject(error);
}
)
// Response interceptors
service.interceptors.response.use(
async (response: AxiosResponse) => {
// await new Promise(resovle => setTimeout(resovle, 3000))
Toast.clear();
const res = response.data;
if (res.code !== 0) {
// token 過時
if (res.code === 401)
// 警告提示窗
return;
if (res.code == 403) {
Dialog.alert({
title: "警告",
message: res.msg
}).then(() => {})
return
}
// 若後臺返回錯誤值,此處返回對應錯誤對象,下面 error 就會接收
return Promise.reject(new Error(res.msg || "Error"))
}
// 注意返回值
else return response.data
},
(error: any) => {
Toast.clear();
if (error && error.response) {
switch (error.response.status) {
case 400:
error.message = "請求錯誤(400)"
break
case 401:
error.message = "未受權,請登陸(401)"
break
case 403:
error.message = "拒絕訪問(403)"
break
case 404:
error.message = `請求地址出錯: ${error.response.config.url}`
break
case 405:
error.message = "請求方法未容許(405)"
break
case 408:
error.message = "請求超時(408)"
break
case 500:
error.message = "服務器內部錯誤(500)"
break
case 501:
error.message = "服務未實現(501)"
break
case 502:
error.message = "網絡錯誤(502)"
break
case 503:
error.message = "服務不可用(503)"
break
case 504:
error.message = "網絡超時(504)"
break
case 505:
error.message = "HTTP版本不受支持(505)"
break
default:
error.message = `鏈接錯誤: ${error.message}`
}
} else {
if (error.message == "Network Error") error.message == "網絡異常,請檢查後重試!"
error.message = "鏈接到服務器失敗,請聯繫管理員"
}
Toast(error.message)
// store.auth.clearAuth()
// store.dispatch("clearAuth")
return Promise.reject(error)
}
)
export default service
複製代碼
src文件夾
下面,建立config文件夾
,放index.ts
export interface IConfig {
env: string // 開發環境
mock?: boolean // mock數據
title: string // 項目title
baseUrl?: string // 項目地址
baseApi?: string // api請求地址
APPID?: string // 公衆號appId 通常放在服務器端
APPSECRET?: string // 公衆號appScript 通常放在服務器端
}
const dev: IConfig = {
env: "development",
mock: false,
title: "開發",
baseUrl: "http://localhost:8001", // 項目地址
baseApi: "https://baidu.com/api", // 本地api請求地址,注意:若是你使用了代理,請設置成'/'
APPID: "wx123456778890",
APPSECRET: "xxx"
}
const prod: IConfig = {
env: "production",
mock: false,
title: "生產",
baseUrl: "https://www.xxx.com/", // 正式項目地址
baseApi: "https://www.baidu.com/api", // 正式api請求地址
APPID: "wx1234567890",
APPSECRET: "xxx"
}
export const config: IConfig = import.meta.env.MODE == 'development' ? dev : prod
複製代碼
.env.development
和.env.production
文件在根目錄下,建立.env.development
和.env.production
文件ios
NODE_ENV='development'
# must start with VUE_APP_
VUE_APP_ENV = 'development'
OUTPUT_DIR = 'test'
複製代碼
NODE_ENV='production'
# must start with VUE_APP_
VUE_APP_ENV = 'production'
OUTPUT_DIR = 'dist'
複製代碼
package.json
文件在scripts裏面,修改爲...web
根據不同的命令,走不一樣的config接口面試
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"prod": "cross-env NODE_ENV=dev vue-cli-service serve --mode production",
"lint": "vue-cli-service lint --mode development"
}
複製代碼
至此 request的封裝和config請求信息抽離已經完成vuex
dev環境和prod環境也已經處理完成vue-cli
在utils
裏面建立storage.ts文件
, 放置storage文件typescript
/**
* 封裝操做localstorage本地存儲的方法
*/
export const storage = {
//存儲
set(key: string, value: any) {
localStorage.setItem(key, JSON.stringify(value))
},
//取出數據
get<T>(key: string) {
const value = localStorage.getItem(key)
if (value && value != "undefined" && value != "null") {
return <T>JSON.parse(value)
}
},
// 刪除數據
remove(key: string) {
localStorage.removeItem(key)
}
};
/**
* 封裝操做sessionStorage本地存儲的方法
*/
export const sessionStorage = {
//存儲
set(key: string, value: any) {
window.sessionStorage.setItem(key, JSON.stringify(value))
},
//取出數據
get<T>(key: string) {
const value = window.sessionStorage.getItem(key)
if (value && value != "undefined" && value != "null") {
return JSON.parse(value)
}
return null
},
// 刪除數據
remove(key: string) {
window.sessionStorage.removeItem(key)
}
}
複製代碼
搞掂收工,有不懂的儘管問,我有空就會回覆的啦npm
大佬們,感興趣能夠關注我公衆號鴨,如今仍是個位數呢,委屈屈...
人懶,不想配圖,望能幫到你們
公衆號:
小何成長
,佛系更文,都是本身曾經踩過的坑或者是學到的東西有興趣的小夥伴歡迎關注我哦,我是:
何小玍。
你們一塊兒進步鴨