Tutorial

Even More Advanced Routing with Vue: Data Fetching

Published on March 23, 2020
Default avatar

By Jim Toth

Even More Advanced Routing with Vue: Data Fetching

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

In the last post, More Advanced Routing with Vue, we covered using Transitions with Vue Router. This time we’ll cover Data Fetching with Vue Router.

Data Fetching allows us to load asynchronous data in our routed components. We can also specify whether data is fetched before or after a component is loaded. Both of these strategies are equally viable but have different implementations. We’ll cover both.

Vue Project Setup

Since this is yet another post about advanced Vue Router techniques, we’ll assume you’re already familiar with the basic setup. However, let’s define a starting point that we’ll use for the rest of the post:

# Yarn
$ yarn add vue-router

# npm
$ npm install vue-router --save
main.js
import Vue from 'vue';
import VueRouter from 'vue-router';

import App from './App';
import Swamp from './components/Swamp';
import Gator from './components/Gator';

Vue.use(VueRouter);

const router = new VueRouter({
  routes: [
    { path: '/swamp', component: Swamp },
    { path: '/gator', component: Gator }
  ]
});

new Vue({
  render: h => h(App),
  router
}).$mount('#app')
App.vue
<template>
  <div id="app">
    <div class="nav">
      <router-link to="/swamp">Swamp</router-link> |
      <router-link to="/gator">Gator</router-link>
    </div>
    <hr />
    <div class="router-view">
      <router-view></router-view>
    </div>
  </div>
</template>

<script>
export default { name: 'App' }
</script>
components/Swamp.vue
<template>
  <div>Welcome to the Swamp, {{ name }}!</div>
</template>

<script>
export default {
  name: 'Swamp',
  data() {
    return { name: null }
  },
}
</script>
components/Gator.vue
<template>
  <div>Howdy, Gator {{ name }}!</div>
</template>

<script>
export default {
  name: 'Gator',
  data() {
    return { name: null }
  }
}
</script>

Data Fetching

Let’s say we had a function that mocked a simple HTTP GET called pretendGet():

scripts/pretendGet.js
export default (callback) => {
  setTimeout(() => {
    callback(null, 'Alice');
  }, 500);
}

After 500ms pretendGet() will return the string 'Alice' to the callback method callback. We’ll use this to mock a server request in the following examples.

Fetching before navigation

Fetching before navigation allows us to ensure that our routed components have the data they need before being displayed to the user. In this approach we added a beforeRouteEnter method which Vue Router calls when the user requests to navigate to this component but before it has loaded. We also define a beforeRouteUpdate method which is called when the route changes. This is useful if you’re fetching data related to a route parameter which is accessible via to.params.

components/Gator.vue
import pretendGet from '../scripts/pretendGet';

export default {
  name: 'Gator',
  data() {
    return { name: null }
  },
  // Component not loaded yet
  beforeRouteEnter(to, from, next) {
    pretendGet((err, name) => {
      next(vm => vm.setName(err, name));
    });
  },
  // Component already loaded and route changes
  beforeRouteUpdate(to, from, next) {
    this.name = null;
    pretendGet((err, name) => {
      this.setName(err, name);
      next();
    });
  },
  methods: {
    setName(err, name) {
      if (err) {
        console.error(err);
      } else {
        this.name = name;
      }
    }
  }
}

Keep in mind that navigation will not happen until data is fetched. Because of this, it’s a good idea to display some kind of progress bar or indicator that data is being fetched. If there’s an error, it would also be a good idea to display that as well.

Fetching after navigation

Fetching after navigation is also a valid approach. In this case we’ll utilize the created() lifecycle hook to call our data fetching method fetchName(). We’ll also define a watch property on $route so we can call fetchName() whenever the route changes.

components/Swamp.vue
import pretendGet from '../scripts/pretendGet';

export default {
  name: 'Swamp',
  data() {
    return { name: null }
  },
  created() {
    this.fetchName();
  },
  watch: {
    // Re-fetch when route changes
    '$route': 'fetchName'
  },
  methods: {
    fetchName() {
      pretendGet((err, name) => {
        if (err) {
          console.error(err);
        } else {
          this.name = name;
        }
      });
    }
  }
}

Keep in mind that with this approach we’ll have to account for data not being ready when the component is first rendered. It’s a good idea to include placeholders or skeleton placeholders along with indicators to let the user know that data is being fetched along with any errors that might occur.

Wrapping Up

Vue Router Data Fetching is a great way to ensure a smooth user experience for your components that rely on fetching data from external sources. Fetching before navigation is a good approach if you’re a fan of using app-wide notifications or progress indicators. If you’d rather handle this kind of stuff on a component level then fetching after navigation might be the right approach for you. As always, make sure to read the docs!

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Jim Toth

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel