02-yarn整合axios

0 vite环境变量

  • 在浏览器环境里使用环境变量,打印如下变量
console.log('import', import.meta) 
#打印内容:
{
    "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} 应用运行的模式。
import.meta.env.BASE_URL: {string} 部署应用时的基本 URL。他由base 配置项决定。
import.meta.env.PROD: {boolean} 应用是否运行在生产环境。
import.meta.env.DEV: {boolean} 应用是否运行在开发环境 (永远与import.meta.env.PROD相反)。
  • 在项目根目录下创建.env文件,内容
VITE_BASE_URL=http://192.168.19.14:9000
  • 在ts代码中通过,如下方式引用
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')
  • 安装插件
//需要分别安装这两个插件
yarn add @types/node
//使用 vite-plugin-compression 可以 gzip 或 brotli 的方式来压缩资源,这一步需要服务器端的配合,vite 只能帮你打包出 .gz 文件。此插件使用简单,你甚至无需配置参数,引入即可。
//开启 gzip 可以极大的压缩静态资源,对页面加载的速度起到了显著的作用。
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导入axios

yarn add axios
#qs 依赖 (对请求传的参数转json字符串处理工具)
yarn add qs
  • 在src目录下创建utils/request.ts 文件
//引入 axios
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
import { debug } from "console";
import qs from "qs";
// //允许跨域携带cookie信息 改配置与后端保持一致
axios.defaults.withCredentials = true;
// 设置重新请求次数
axios.defaults.retry = 10;
// 设置请求延时
axios.defaults.retryDelay = 5000
// 接口类型和方法
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;
}
// 取消重复请求
const CancelToken = axios.CancelToken;
// 用于存储每个请求的取消函数以及对应标识
let sources: any = [];
// 取消函数
let removeSource = (config: any) => {
    for (let item in sources) {
        if (sources[item].cancelFunction === config.url + "&" + config.method) {
            sources[item].cancel("已取消重复请求,请勿重复请求");
            sources.splice(item, 1);
        }
    }
};
let viteURL = import.meta.env.VITE_BASE_URL;
console.log("当前环境的基础路径为:" + viteURL);
class AxiosHttpRequest implements BaseType {
    baseURL: string;
    timeout: number;
    constructor(baseURL: string, timeout: number) {
        this.baseURL = viteURL;
        this.timeout = 10000;
    }
    // 配置参数
    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;
    }
    // 拦截设置
    interceptors(config: AxiosInstance, url: string | number | undefined) {
        // debugger;
        // 请求拦截
        config.interceptors.request.use(
            (config: AxiosRequestType) => {
                // 断网提示 拦截器不在线提示用户网络有问题
                if (!navigator.onLine) {
                    // messageUtil.warn("您的网络故障,请检查!");
                    return;
                }
                // 取消重复请求
                removeSource(config);
                config.cancelToken = new CancelToken((c) => {
                    // 将取消函数存起来
                    sources.push({
                        cancelFunction: config.url + "&" + config.method,
                        cancel: c,
                    });
                });                
                // 添加全局的loading..
                // loadingUtil.show();
                //全局参数统一处理
                if (config.method === "post") {
                    config.data = { ...config.data };
                } else {
                    config.params = { ...config.params };
                }
                // 请求头携带token
                // get请求映射params参数
                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.获取时间戳,精确到秒
                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.添加请求头token
                    // if (userStore().token && userStore().getToken != "") {
                    //   config.headers["Authentication"] = userStore().getToken;
                    // } else {
                    //   //token 不存在跳转到登录页
                    //   router.replace("/login");
                    // }
                }
                return config;
            },
            (error: any) => {
                return Promise.reject(error);
            }
        );

        // 响应拦截
        config.interceptors.response.use(
            (res: any) => {
                // debugger;
                // 取消重复请求
                removeSource(res.config);
                // 获取错误信息
                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);
                                    //重新发送请求 TODO
                                    var config = res.config;
                                    return axios(config);
                                });
                            break;
                        case "A0313":
                            //  messageUtil.error("权限不足,请联系管理员");
                            return Promise.reject(res);
                    }
                } else {
                    return Promise.resolve(res);
                }
            },
            (error: any) => {
                console.error(`axios请求异常:${error}`)
                // debugger;
                let msg: string;
                if (error.response) {
                    let code: number = error.response.status;
                    switch (code) {
                        case 400:
                            msg = "错误请求";
                            break;
                        case 401:
                            msg = "认证信息已失效";
                            // router.push("/login");
                            break;
                        case 403:
                            msg = "客户端非法请求";
                            break;
                        case 404:
                            msg = "访问资源不存在";
                            break;
                        case 405:
                            msg = "请求方式错误";
                            break;
                        case 500:
                            msg = "服务器内部异常";
                            break;
                        case 503:
                            msg = "服务不可用";
                            break;
                        case 504:
                            msg = "网络超时";
                            break;
                        case 505:
                            msg = "http版本不支持该请求";
                            break;
                        default:
                            msg = "未知错误,请联系管理员";
                            break;
                    }
                } else {
                    msg = error.message;
                    if (msg == "Network Error") {
                        msg = "后端接口连接异常";
                    } else if (msg.includes("timeout")) {
                        msg = "系统接口请求超时";
                    } else if (msg.includes("Request failed with status code")) {
                        msg = "系统接口" + msg.substring(msg.length - 3) + "异常";
                    }
                }
                return Promise.reject(error);
            }
        );
    }
    /**
     * 外部调用方法
     * @param options axios请求参数
     * @returns 实例
     */
    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" });
    }
}
// 实例化请求类
const http = new AxiosHttpRequest(viteURL, 3000);
export default http;
  • 创建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 创建路由及自定义视图

  • 文件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 = () => {
    // 登录事件
    //调用登录请求
    login(form).then((response: any): void => {
        //  写逻辑的地方 · · · 
        console.log('登录请求:', response);
    });
    // oks().then((response: any): void => {     
    //     console.log('测试get方法:', response);
    // });
}
</script>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容