Vue 3 Project Setup and Core Integration Patterns

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 sass for 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);
});

Tags: vue3 Vite axios echarts TypeScript

Posted on Mon, 11 May 2026 08:25:02 +0000 by Aimless