Modular Axios Architecture for Vue Applications

Directory Organization

Separating HTTP configuration from API definitions ensures maintainability. Place the base Axios instance in src/services/httpClient.js and specific endpoint definitions in src/api/postEndpoints.js.

Base HTTP Client Configuration

Initialize an Axios instance with a base URL to avoid repeating the root endpoint across the application.

// src/services/httpClient.js
import axios from 'axios';

const API_BASE_URL = 'https://api.example.com';

const httpClient = axios.create({
  baseURL: API_BASE_URL,
  timeout: 5000
});

export default httpClient;

Domain-Specific API Modules

Group related endpoints into dedicated modules. Import the custom HTTP client to construct requests.

// src/api/postEndpoints.js
import httpClient from '@/services/httpClient';

export const fetchPosts = (currentPage, itemsPerPage) => {
  return httpClient.get('/posts', {
    params: {
      page: currentPage,
      size: itemsPerPage
    }
  });
};

Component Integration

Consume the modularized API within Vue components. The following example demonstrates handling infinite scrolling and pull-to-refresh functionality.

<template>
  <div class="feed-container">
    <van-pull-refresh v-model="refreshing" :disabled="allLoaded" @refresh="handleRefresh">
      <van-list v-model="fetching" :finished="allLoaded" finished-text="End of feed" @load="loadMore">
        <PostItem
          v-for="item in feedItems"
          :key="item.id"
          :title="item.title"
          :author="item.author"
          :date="item.publishedAt"
        />
      </van-list>
    </van-pull-refresh>
  </div>
</template>

<script>
import { fetchPosts } from '@/api/postEndpoints';
import PostItem from '@/components/PostItem.vue';

export default {
  name: 'FeedView',
  components: { PostItem },
  data() {
    return {
      currentPage: 1,
      pageSize: 10,
      feedItems: [],
      fetching: true,
      allLoaded: false,
      refreshing: false
    };
  },
  created() {
    this.loadFeedData();
  },
  methods: {
    async loadFeedData(isPullDown = false) {
      const { data: response } = await fetchPosts(this.currentPage, this.pageSize);

      if (isPullDown) {
        this.feedItems = [...response, ...this.feedItems];
        this.refreshing = false;
      } else {
        this.feedItems = [...this.feedItems, ...response];
        this.fetching = false;
      }

      if (response.length === 0) {
        this.allLoaded = true;
      }
    },
    loadMore() {
      this.currentPage += 1;
      this.loadFeedData();
    },
    handleRefresh() {
      this.currentPage += 1;
      this.loadFeedData(true);
    }
  }
};
</script>

<style scoped>
.feed-container {
  padding: 50px 15px;
}
</style>

Tags: vue axios javascript frontend modular-design

Posted on Fri, 18 Sep 2026 16:44:25 +0000 by mouse02