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 + "×tamp=" + 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>