Project Initializasion and Dependencies
To establish a modern Vue 3 ecosystem, begin by scaffolding the application using Vite. Subsequently, install necessary libraries categorized by their usage environment:
- Scaffolding: Initialize the project structure with Vue 3.
- Development Dependencies: Install
sassfor stylesheet processing. - Runtime Dependencies: Acquire asynchronous communication tools, UI component suites, and utility libraries.
# Create project
npm init vue@latest
# Dev dependencies
npm i sass -D
# Runtime dependencies
npm install axios element-plus @element-plus/icons-vue
npm install echarts ts-md5 pinia-plugin-persist
npm install vue3-count-to
Axios Client Configuration
Centralize HTTP requests using a configured axios instance. This setup includes baseURL configuration, timeout handling, and global interceptors for request logging and response validation.
import axios, { type AxiosInstance, InternalAxiosRequestConfig } from "axios";
import { ElMessage } from "element-plus";
// Configuration object
const httpOptions = {
baseURL: import.meta.env.VITE_API_ENDPOINT,
timeout: 5000,
};
export const apiClient: AxiosInstance = axios.create(httpOptions);
// Request Interceptor
apiClient.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
console.log("[Request Interceptor]", config);
return config;
},
(error) => {
return Promise.reject(error);
}
);
// Response Interceptor
apiClient.interceptors.response.use(
(response) => {
console.log("[Response Interceptor]", response);
const { data } = response;
// Check business logic status codes
if (data.code === 200 || data.flag) {
return response;
}
ElMessage.error(data.msg);
return Promise.reject(new Error(data.msg));
},
(error) => {
const message = error.message;
if (message.includes("Network")) {
ElMessage.error("Network connectivity issue");
} else if (message.includes("Param")) {
ElMessage.error("Invalid parameters detected");
}
return Promise.reject(error);
}
);
export default apiClient;
API Method Definitions
Define API endpoints using functional modules. Distinguish between GET, POST, PUT, and DELETE operations based on payload transmission reuqirements (JSON vs Form-data).
import apiClient from "@/utils/request";
const USER_RESOURCE = "/user/";
export async function authenticateUser(username: string, password: string) {
return apiClient({
url: `${USER_RESOURCE}auth?username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}`,
method: "get",
});
}
export async function createAccount(payload: RegisterDto) {
return apiClient({
url: `${USER_RESOURCE}register`,
method: "post",
data: payload,
});
}
export async function updateProfile(updatePayload: UserUpdateDto) {
return apiClient({
url: `${USER_RESOURCE}update`,
method: "put",
data: updatePayload,
});
}
export async function deleteUserTarget(id: string) {
return apiClient({
url: `${USER_RESOURCE}delete/${id}`,
method: "delete",
});
}
TypeScript Interface Declarations
Incorporate type declaration files (.d.ts) to define static data structures. These files declare types for external JSON responses or localized constants with out implementing logic, ensuring full IDE support and preventing runtime errors.
// types/geography.d.ts
export interface GeographicRegion {
id: string;
name: string;
}
export interface AddressCascadeModel {
provinceId: string;
cityId: string;
districtId: string;
}
export interface LocationData {
region: GeographicRegion;
children?: GeographicRegion[];
}
ECharts Visualization Lifecycle
Integrate charts by initializing instances during component mounting and disposing them before unmounting to manage memory. Ensure the container size is handled correctly when window dimensions change.
import { ref, reactive, onMounted, onUnmounted } from 'vue';
import * as echarts from 'echarts';
import 'echarts/theme/vintage';
const chartContainer = ref<HTMLDivElement>();
let chartInstance: any = null;
const configureChart = () => {
if (!chartContainer.value) return;
// Initialize with theme
chartInstance = echarts.init(chartContainer.value, 'vintage');
// Set complex options
chartInstance.setOption({
title: { text: 'Analytics Overview' },
tooltip: { trigger: 'axis' },
// Add series configuration here
});
};
const handleResize = () => {
if (chartInstance) {
chartInstance.resize();
}
};
onMounted(() => {
configureChart();
window.addEventListener('resize', handleResize);
});
onUnmounted(() => {
if (chartInstance) {
chartInstance.dispose();
chartInstance = null;
}
window.removeEventListener('resize', handleResize);
});