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>