02-yarn整合axios

0 vite環(huán)境變量

  • 在瀏覽器環(huán)境里使用環(huán)境變量拗军,打印如下變量
console.log('import', import.meta) 
#打印內(nèi)容:
{
    "url": "http://localhost:5173/src/components/home.vue",
    "hot": {
        "data": {}
    },
    "env": {
        "BASE_URL": "/",
        "MODE": "development",
        "DEV": true,
        "PROD": false,
        "SSR": false
    }
}
console.log('import.url', import.meta.env.BASE_URL)
#   /
console.log('import.env.MODE', import.meta.env.MODE)
# development
import.meta.env.MODE: {string} 應(yīng)用運(yùn)行的模式。
import.meta.env.BASE_URL: {string} 部署應(yīng)用時(shí)的基本 URL易阳。他由base 配置項(xiàng)決定。
import.meta.env.PROD: {boolean} 應(yīng)用是否運(yùn)行在生產(chǎn)環(huán)境。
import.meta.env.DEV: {boolean} 應(yīng)用是否運(yùn)行在開(kāi)發(fā)環(huán)境 (永遠(yuǎn)與import.meta.env.PROD相反)励背。
  • 在項(xiàng)目根目錄下創(chuàng)建.env文件,內(nèi)容
VITE_BASE_URL=http://192.168.19.14:9000
  • 在ts代碼中通過(guò)砸西,如下方式引用
import.meta.env.VITE_BASE_URL

1 yarn整合element-plus

  • yarn安裝element-plus
yarn add element-plus
yarn add vite @vitejs/plugin-vue
  • 修改main.ts叶眉,加入element-plus
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { router } from './router'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
createApp(App).use(router).use(ElementPlus).mount('#app')
  • 安裝插件
//需要分別安裝這兩個(gè)插件
yarn add @types/node
//使用 vite-plugin-compression 可以 gzip 或 brotli 的方式來(lái)壓縮資源,這一步需要服務(wù)器端的配合芹枷,vite 只能幫你打包出 .gz 文件衅疙。此插件使用簡(jiǎn)單,你甚至無(wú)需配置參數(shù)鸳慈,引入即可饱溢。
//開(kāi)啟 gzip 可以極大的壓縮靜態(tài)資源,對(duì)頁(yè)面加載的速度起到了顯著的作用走芋。
yarn add vite-plugin-compression
  • 修改vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import viteCompression from "vite-plugin-compression"
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), viteCompression({
    verbose: true,
    disable: false,
    threshold: 10240,
    algorithm: "gzip",
    ext: ".gz",
  })],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "src"),
    },
  },
})

2 yarn導(dǎo)入axios

yarn add axios
#qs 依賴 (對(duì)請(qǐng)求傳的參數(shù)轉(zhuǎn)json字符串處理工具)
yarn add qs
  • 在src目錄下創(chuàng)建utils/request.ts 文件
//引入 axios
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
import { debug } from "console";
import qs from "qs";
// //允許跨域攜帶cookie信息 改配置與后端保持一致
axios.defaults.withCredentials = true;
// 設(shè)置重新請(qǐng)求次數(shù)
axios.defaults.retry = 10;
// 設(shè)置請(qǐng)求延時(shí)
axios.defaults.retryDelay = 5000
// 接口類(lèi)型和方法
interface BaseType {
    baseURL: string;
    getConfigParams(): any;
    interceptors(instance: AxiosInstance, url: string | number | undefined): any;
    request(options: AxiosRequestConfig): any;
}
interface AxiosRequestType {
    baseURL?: string;
    url?: string | undefined;
    data?: any;
    params?: any;
    method?: string;
    headers?: any;
    timeout?: number;
    value?: any;
    cancelToken?: any;
}
// 取消重復(fù)請(qǐng)求
const CancelToken = axios.CancelToken;
// 用于存儲(chǔ)每個(gè)請(qǐng)求的取消函數(shù)以及對(duì)應(yīng)標(biāo)識(shí)
let sources: any = [];
// 取消函數(shù)
let removeSource = (config: any) => {
    for (let item in sources) {
        if (sources[item].cancelFunction === config.url + "&" + config.method) {
            sources[item].cancel("已取消重復(fù)請(qǐng)求绩郎,請(qǐng)勿重復(fù)請(qǐng)求");
            sources.splice(item, 1);
        }
    }
};
let viteURL = import.meta.env.VITE_BASE_URL;
console.log("當(dāng)前環(huán)境的基礎(chǔ)路徑為:" + viteURL);
class AxiosHttpRequest implements BaseType {
    baseURL: string;
    timeout: number;
    constructor(baseURL: string, timeout: number) {
        this.baseURL = viteURL;
        this.timeout = 10000;
    }
    // 配置參數(shù)
    getConfigParams() {
        const config = {
            baseURL: this.baseURL,
            timeout: this.timeout,
            headers: {
                "Content-Type": "application/json;charset=UTF-8",
                "Access-Control-Allow-Credentials": "true",
                "Access-Control-Allow-Origin": "*",
                "Access-Control-Allow-Methods": "*"
            },
        };
        return config;
    }
    // 攔截設(shè)置
    interceptors(config: AxiosInstance, url: string | number | undefined) {
        // debugger;
        // 請(qǐng)求攔截
        config.interceptors.request.use(
            (config: AxiosRequestType) => {
                // 斷網(wǎng)提示 攔截器不在線提示用戶網(wǎng)絡(luò)有問(wèn)題
                if (!navigator.onLine) {
                    // messageUtil.warn("您的網(wǎng)絡(luò)故障潘鲫,請(qǐng)檢查!");
                    return;
                }
                // 取消重復(fù)請(qǐng)求
                removeSource(config);
                config.cancelToken = new CancelToken((c) => {
                    // 將取消函數(shù)存起來(lái)
                    sources.push({
                        cancelFunction: config.url + "&" + config.method,
                        cancel: c,
                    });
                });                
                // 添加全局的loading..
                // loadingUtil.show();
                //全局參數(shù)統(tǒng)一處理
                if (config.method === "post") {
                    config.data = { ...config.data };
                } else {
                    config.params = { ...config.params };
                }
                // 請(qǐng)求頭攜帶token
                // get請(qǐng)求映射params參數(shù)
                if (config.method === "get" && config.params) {
                    let url = config.url + "?";
                    for (const propName of Object.keys(config.params)) {
                        const value = config.params[propName];
                        var part = encodeURIComponent(propName) + "=";
                        if (value !== null && typeof value !== "undefined") {
                            if (typeof value === "object") {
                                for (const key of Object.keys(value)) {
                                    let params = propName + "[" + key + "]";
                                    var subPart = encodeURIComponent(params) + "=";
                                    url += subPart + encodeURIComponent(value[key]) + "&";
                                }
                            } else {
                                url += part + encodeURIComponent(value) + "&";
                            }
                        }
                    }
                    url = url.slice(0, -1);
                    config.params = {};
                    config.url = url;
                }

                //2.獲取時(shí)間戳,精確到秒
                let getTimestamp = Date.now().toString().substring(0, 10);
                let url = config.url;
                if (url) {
                    let indexOf = url.indexOf("?");
                    if (indexOf > -1) {
                        config.url = config.url + "&timestamp=" + getTimestamp;
                    } else {
                        config.url = config.url + "?timestamp=" + getTimestamp;
                    }
                }
                if (config.headers) {
                    // config.headers["Content-Type"] = "application/json;charset=UTF-8";
                    // config.headers["Access-Control-Allow-Credentials"] = true;
                    // config.headers["Access-Control-Allow-Origin"] = "*";
                    // config.headers["Access-Control-Allow-Methods"] = "*";
                    // console.log("獲取pinia中的token:" + userStore().getToken);
                    // //3.添加請(qǐng)求頭token
                    // if (userStore().token && userStore().getToken != "") {
                    //   config.headers["Authentication"] = userStore().getToken;
                    // } else {
                    //   //token 不存在跳轉(zhuǎn)到登錄頁(yè)
                    //   router.replace("/login");
                    // }
                }
                return config;
            },
            (error: any) => {
                return Promise.reject(error);
            }
        );

        // 響應(yīng)攔截
        config.interceptors.response.use(
            (res: any) => {
                // debugger;
                // 取消重復(fù)請(qǐng)求
                removeSource(res.config);
                // 獲取錯(cuò)誤信息
                if (res.data.body) {
                    let errCode = res.data.body.errCode;
                    switch (errCode) {
                        //token失效重新獲取token
                        case "A0225":
                            http
                                .get({
                                    url: viteURL + "/token/refreshToken",
                                })
                                .then((res: any) => {
                                    // localStorageUtil.set("accessToken", res.data);
                                    //重新發(fā)送請(qǐng)求 TODO
                                    var config = res.config;
                                    return axios(config);
                                });
                            break;
                        case "A0313":
                            //  messageUtil.error("權(quán)限不足肋杖,請(qǐng)聯(lián)系管理員");
                            return Promise.reject(res);
                    }
                } else {
                    return Promise.resolve(res);
                }
            },
            (error: any) => {
                console.error(`axios請(qǐng)求異常:${error}`)
                // debugger;
                let msg: string;
                if (error.response) {
                    let code: number = error.response.status;
                    switch (code) {
                        case 400:
                            msg = "錯(cuò)誤請(qǐng)求";
                            break;
                        case 401:
                            msg = "認(rèn)證信息已失效";
                            // router.push("/login");
                            break;
                        case 403:
                            msg = "客戶端非法請(qǐng)求";
                            break;
                        case 404:
                            msg = "訪問(wèn)資源不存在";
                            break;
                        case 405:
                            msg = "請(qǐng)求方式錯(cuò)誤";
                            break;
                        case 500:
                            msg = "服務(wù)器內(nèi)部異常";
                            break;
                        case 503:
                            msg = "服務(wù)不可用";
                            break;
                        case 504:
                            msg = "網(wǎng)絡(luò)超時(shí)";
                            break;
                        case 505:
                            msg = "http版本不支持該請(qǐng)求";
                            break;
                        default:
                            msg = "未知錯(cuò)誤溉仑,請(qǐng)聯(lián)系管理員";
                            break;
                    }
                } else {
                    msg = error.message;
                    if (msg == "Network Error") {
                        msg = "后端接口連接異常";
                    } else if (msg.includes("timeout")) {
                        msg = "系統(tǒng)接口請(qǐng)求超時(shí)";
                    } else if (msg.includes("Request failed with status code")) {
                        msg = "系統(tǒng)接口" + msg.substring(msg.length - 3) + "異常";
                    }
                }
                return Promise.reject(error);
            }
        );
    }
    /**
     * 外部調(diào)用方法
     * @param options axios請(qǐng)求參數(shù)
     * @returns 實(shí)例
     */
    request(options: AxiosRequestConfig) {
        const instance = axios.create();
        options = Object.assign(this.getConfigParams(), options);
        this.interceptors(instance, options.url);
        return instance(options);
    }

    get<T>(config: AxiosRequestConfig) {
        return this.request({ ...config, method: "GET" });
    }
    post<T>(config: AxiosRequestConfig) {
        return this.request({ ...config, method: "POST" });
    }
    put<T>(config: AxiosRequestConfig) {
        return this.request({ ...config, method: "PUT" });
    }
    delete<T>(config: AxiosRequestConfig) {
        return this.request({ ...config, method: "DELETE" });
    }
    patch<T>(config: AxiosRequestConfig) {
        return this.request({ ...config, method: "PATCH" });
    }
}
// 實(shí)例化請(qǐng)求類(lèi)
const http = new AxiosHttpRequest(viteURL, 3000);
export default http;
  • 創(chuàng)建src/api/index.ts
import http from "../utils/request";
export function login(data: any) {
  return http.post({
    url: "/user-root/users/login",
    data,
  });
}
export function oks() {
  return http.get({
    url: "/user-root/users/oks"
  });
}

3 創(chuàng)建路由及自定義視圖

  • 文件src/router/index.ts
<template>
    <el-container>
        <el-form :model="form" label-width="120px">
            <el-form-item label="Activity name">
                <el-input v-model="form.userName" />
            </el-form-item>
            <el-form-item label="Activity zone">
                <el-input v-model="form.passWord" type="password" placeholder="Please input password" show-password />
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="onSubmit">Login</el-button>
                <el-button>Cancel</el-button>
            </el-form-item>
        </el-form>
    </el-container>
</template>
<script setup lang="ts">
import { reactive } from 'vue'
import { login, oks } from '../api/index'
// do not use same name with ref
const form = reactive({
    userName: '',
    passWord: ''
})
const onSubmit = () => {
    // 登錄事件
    //調(diào)用登錄請(qǐng)求
    login(form).then((response: any): void => {
        //  寫(xiě)邏輯的地方 · · · 
        console.log('登錄請(qǐng)求:', response);
    });
    // oks().then((response: any): void => {     
    //     console.log('測(cè)試get方法:', response);
    // });
}
</script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市状植,隨后出現(xiàn)的幾起案子浊竟,更是在濱河造成了極大的恐慌,老刑警劉巖津畸,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件振定,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡肉拓,警方通過(guò)查閱死者的電腦和手機(jī)后频,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)帝簇,“玉大人徘郭,你說(shuō)我怎么就攤上這事∩ル龋” “怎么了残揉?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)芋浮。 經(jīng)常有香客問(wèn)我抱环,道長(zhǎng),這世上最難降的妖魔是什么纸巷? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任镇草,我火速辦了婚禮,結(jié)果婚禮上瘤旨,老公的妹妹穿的比我還像新娘梯啤。我一直安慰自己,他們只是感情好存哲,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布因宇。 她就那樣靜靜地躺著,像睡著了一般祟偷。 火紅的嫁衣襯著肌膚如雪察滑。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天修肠,我揣著相機(jī)與錄音贺辰,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛饲化,可吹牛的內(nèi)容都是我干的莽鸭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼吃靠,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蒋川!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起撩笆,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缸浦,沒(méi)想到半個(gè)月后夕冲,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡裂逐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年歹鱼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卜高。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡弥姻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出掺涛,到底是詐尸還是另有隱情庭敦,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布薪缆,位于F島的核電站秧廉,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏拣帽。R本人自食惡果不足惜疼电,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望减拭。 院中可真熱鬧蔽豺,春花似錦、人聲如沸拧粪。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)既们。三九已至濒析,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間啥纸,已是汗流浹背号杏。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人盾致。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓主经,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親庭惜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子罩驻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容