DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Building Micro-Frontends With Vue and Reusable Components
  • Designing Self-Healing AI Infrastructure: The Role of Autonomous Recovery
  • Advanced Middleware Architecture For Secure, Auditable, and Reliable Data Exchange Across Systems
  • Architecting AI-Native Cloud Platforms: Signals to Insights to Actions

Trending

  • Compliance Automated Standard Solution (COMPASS), Part 10: How OSCAL Mapping Paves the Way for Continuous Compliance Scalability
  • The Agentic Agile Office: Streamlining Enterprise Agile With Autonomous AI Agents
  • Offline-First Patch Management for 10,000 Edge Nodes: A Practical Architecture That Scales
  • A Hands-On ABAP RESTful Programming Model Guide
  1. DZone
  2. Coding
  3. JavaScript
  4. 4 AJAX Patterns for Vue.js Apps

4 AJAX Patterns for Vue.js Apps

By 
Anthony Gore user avatar
Anthony Gore
·
Updated Feb. 04, 20 · Tutorial
Likes (7)
Comment
Save
Tweet
Share
17.3K Views

Join the DZone community and get the full member experience.

Join For Free

If you ask two Vue.js developers "what's the best way to use AJAX in an app?" you'll get three different opinions.

Vue doesn't provide an official way of implementing AJAX, and there are a number of different design patterns that may be used effectively. Each comes with its own pros and cons and should be judged based on the requirements. You may even use several simultaneously!

In this article, I'll show you four places you can implement AJAX in a Vue app:

  1. Root instance.
  2. Components.
  3. Vuex actions.
  4. Route navigation guards.

I'll explain each approach, give an example, and cover the pros and cons as well.

1. Root Instance

With this architecture, you issue all your AJAX requests from the root instance and store all state there too. If any subcomponents need data, it will come down as props. If subcomponents need refreshed data, a custom event will be used to prompt the root instance to request it.

Example:

JavaScript
 




x
22


 
1
new Vue({
2
  data: {
3
    message: ''
4
  },
5
  methods: {
6
    refreshMessage(resource) {
7
      this.$http.get('/message').then((response) {
8
        this.message = response.data.message;
9
      });
10
    }
11
  }
12
})
13

          
14
Vue.component('sub-component', {
15
  template: '<div>{{ message }}</div>',
16
  props: [ 'message' ]
17
  methods: {
18
    refreshMessage() {
19
      this.$emit('refreshMessage');
20
    }
21
  }
22
});



Pros

  • Keeps all your AJAX logic and data in one place.
  • Keeps your components "dumb" so they can focus on presentation.

Cons

  • A lot of props and custom events are needed as your app expands.
You may also like: Creating a Real-Time Data Application Using Vue.js.

2. Components

With this architecture, components are responsible for managing their own AJAX requests and state independently. In practice, you'll probably want to create several "container" components that manage data for their own local group of "presentational" components.

For example, filter-list might be a container component wrapping filter-input and filter-reset, which serve as presentational components. filter-list would contain the AJAX logic, and would manage data for all the components in this group, communicating via props and events.

See Presentational and Container Components by Dan Abramov for a better description of this pattern.

To make implementation of this architecture easier, you can abstract any AJAX logic into a mixin, then use the mixin in a component to make it AJAX-enabled.

JavaScript
 
xxxxxxxxxx
1
22


 
1
let mixin = {
2
  methods: {
3
    callAJAX(resource) {
4
      ...
5
    }
6
  }
7
}
8

          
9
Vue.component('container-comp', {
10
  // No meaningful template, I just manage data for my children
11
  template: '<div><presentation-comp :mydata="mydata"></presentation-comp></div>', 
12
  mixins: [ myMixin ],
13
  data() {
14
    return { ... }
15
  },
16

          
17
})
18

          
19
Vue.component('presentation-comp', {
20
  template: <div>I just show stuff like {{ mydata }}</div>,
21
  props: [ 'mydata' ]
22
})



Pros

  • Keeps components decoupled and reusable.
  • Gets the data when and where it's needed.

Cons

  • Not easy to communicate data with other components or groups of components.
  • Components can end up with too many responsibilities and duplicate functionality.

3. Vuex Actions

With this architecture, you manage both state and AJAX logic in your Vuex store. Components can request new data by dispatching an action.

If you implement this pattern, it's a good idea to return a promise from your action so you can react to the resolution of the AJAX request, e.g. hide the loading spinner, re-enable a button, etc.

JavaScript
 




xxxxxxxxxx
1
34


 
1
store = new Vuex.Store({
2
  state: {
3
    message: ''
4
  },
5
  mutations: {
6
    updateMessage(state, payload) {
7
      state.message = payload
8
    }
9
  },
10
  actions: {
11
    refreshMessage(context) {
12
      return new Promise((resolve) => {
13
        this.$http.get('...').then((response) => {
14
          context.commit('updateMessage', response.data.message);
15
          resolve();
16
        });
17
      });
18
    }
19
  }
20
});
21

          
22
Vue.component('my-component', {
23
  template: '<div>{{ message }}</div>',
24
  methods: {
25
    refreshMessage() {
26
      this.$store.dispatch('refeshMessage').then(() => {
27
        // do stuff
28
      });
29
    }
30
  },
31
  computed: {
32
    message: { return this.$store.state.message; }
33
  }
34
});



I like this architecture because it decouples your state and presentation logic nicely. If you're using Vuex, this is the way to go. If you're not using Vuex, this might be a good enough reason to.

Pros

  • All the pros of the root component architecture, without needing props and custom events.

Cons

  • Adds the overhead of Vuex.

4. Route Navigation Guards

With this architecture, your app is split into pages, and all data required for a page and its subcomponents is fetched when the route is changed.

The main advantage of this approach is that it really simplifies your UI. If components are independently getting their own data, the page will re-render unpredictably as component data gets populated in an arbitrary order.

A neat way of implementing this is to create endpoints on your server for each page e.g. /about, /contact etc, which match the route names in your app. Then you can implement a generic beforeRouteEnter hook that will merge all the data properties into the page component's data:

JavaScript
 




xxxxxxxxxx
1


 
1
import axios from 'axios';
2

          
3
router.beforeRouteEnter((to, from, next) => {
4
  axios.get(`/api${to.path}`).then(({ data }) => {
5
    next(vm => Object.assign(vm.$data, data))
6
  });
7
})



Pros

  • Makes the UI more predictable.

Cons

  • Slower overall, as the page can't render until all the data is ready.
  • Not much help if you don't use routes.

Bonus Pattern: Server-Render the First AJAX Call Into the Page

It’s not advisable to use AJAX to retrieve application state on the initial page load, as it requires an extra round-trip to the server that will delay your app from rendering.

Instead, inject initial application state into an inline script in the head of the HTML page so it’s available to the app as a global variable as soon as it’s needed.

HTML
 




xxxxxxxxxx
1
12


 
1
<html>
2
...
3
<head>
4
  ...
5
  <script type="text/javascript">
6
   window.__INITIAL_STATE__ = '{ "data": [ ... ] }';
7
  </script>
8
</head>
9
<body>
10
  <div id="app"></div>
11
</body>
12
</html>



AJAX can then be used more appropriately for subsequent data fetches.

If you're interested in learning more about this architecture, check out my article Avoid This Common Anti-Pattern In Full-Stack Vue/Laravel Apps.

Thanks to React AJAX Best Practices by Andrew H. Farmer for inspiration.

AJAX app Data (computing) Vue.js Architecture

Published at DZone with permission of Anthony Gore. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Building Micro-Frontends With Vue and Reusable Components
  • Designing Self-Healing AI Infrastructure: The Role of Autonomous Recovery
  • Advanced Middleware Architecture For Secure, Auditable, and Reliable Data Exchange Across Systems
  • Architecting AI-Native Cloud Platforms: Signals to Insights to Actions

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook