I recently developed an application using Vue.js. The app is divided into several modules, each corresponding to a specific route and containing a main component with numerous sub-components/children. Every module has its own store, actions, mutations, getters, and API calls that are dispatched in the created() hooks of components to retrieve necessary data.
Here is a glimpse of my app's structure:
https://i.sstatic.net/umsQ8.png
Candidates.vue
created() {
this.$store.dispatch('$_candidates/getAllCandidates');
},
/modules/candidates/_store/actions.js
import api from '../_api';
const getAllCandidates = (context) => {
api.fetchAllCandidates
.then((response) => {
context.commit('ALL_CANDIDATES_FETCHED', response.data.candidate_list);
})
.catch((error) => {
// eslint-disable-next-line
console.error(error);
});
};
/modules/candidates/_api/index.js
import { fetchData } from '@/helpers';
const allCandidatesEndpoint =
'https://myapiendpoint.io/candidates/list/all';
const fetchAllCandidates = fetchData(allCandidatesEndpoint, 'get');
export default {
fetchAllCandidates,
};
In the beforeCreate() hook of App.vue, I have a helper function to register all of the application modules in one go. I do this by importing the module stores into the helper file and then registering them. Here is my helper file:
helpers.js
import axios from 'axios';
import { store } from '@/store/store';
import candidatesStore from './modules/candidates/_store';
import dashboardStore from './modules/dashboard/_store';
import eventsStore from './modules/events/_store';
import loginStore from './modules/login/_store';
function fetchData(endpoint, requestType, requestBody) {
const apiToken = store.state.apiToken;
delete axios.defaults.auth;
return axios.request({
method: requestType,
data: requestBody,
url: endpoint,
headers: {
'server-token-id': apiToken,
},
})
.then(response => response)
.catch(error => error);
}
/* Register all of the Vuex modules we'll need to manage application state */
function registerVuexModules() {
store.registerModule('$_candidates', candidatesStore);
store.registerModule('$_dashboard', dashboardStore);
store.registerModule('$_events', eventsStore);
store.registerModule('$_login', loginStore);
}
function unregisterVuexModules() {
store.unregisterModule('$_candidates', candidatesStore);
store.unregisterModule('$_dashboard', dashboardStore);
store.unregisterModule('$_events', eventsStore);
store.unregisterModule('$_login', loginStore);
}
export {
fetchData,
registerVuexModules,
unregisterVuexModules,
};
...and I import it into App.vue like this:
beforeCreate() {
registerVuexModules();
},
However, when I import each module, it triggers an unexpected API call, resulting in a 401 error. This behavior persists even after commenting out parts of helpers.js, confirming that the issue lies with the imports rather than the functions themselves.
The peculiar aspects for me include:
API calls are attempted on every reload of the login page, even before the top-level components of modules are created;
Vue-dev-tools fails to track the dispatching of corresponding actions;
Removing all store imports from the helper file stops these phantom API calls.
I attempted lazy-loading components through vue-router to address this issue but experienced no success. Although the bundle size reduced, the unwanted API calls persisted. Here is how I implemented lazy loading:
/router/index.js
import Vue from 'vue';
import Router from 'vue-router';
import axios from 'axios';
import { store } from '../store/store';
/* Lazy load all of the components required for the routes */
const Login = () => import(/* webpackChunkName: "login" */
'@/modules/login/Login');
const Dashboard = () => import(/* webpackChunkName: "dashboard" */
'@/modules/dashboard/Dashboard');
...
const router = new Router({
routes: [
{
path: '/',
name: 'root',
component: Login,
},
{
path: '/login',
name: 'login',
component: Login,
},
{
path: '/dashboard',
name: 'dashboard',
component: Dashboard,
beforeEnter: (to, from, next) => {
guard(to, from, next);
},
},
...
If anyone can shed light on this perplexing behavior or point out any oversights on my part, it would be greatly appreciated.