Skip to content
Please note that GitHub no longer supports Internet Explorer.

We recommend upgrading to the latest Microsoft Edge, Google Chrome, or Firefox.

Learn more
Data preloading for vue-router, similar to Sapper's preload or Nuxt.js's asyncData
JavaScript
Branch: master
Clone or download
Cannot retrieve the latest commit at this time.
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci
.vscode
src
test
.babelrc
.eslintrc.js
.gitignore
.npmignore
LICENSE
README.md
package.json
yarn.lock

README.md

@badrap/preload CircleCI npm

Add a preload function to your vue-router route components, used for prepopulating data before those routes get rendered. Mostly modeled after Sapper's preload, but also similar to Nuxt.js's asyncData and Next.js's getInitialProps.

Installation

$ yarn install --dev @badrap/preload

Usage

A modified of the following examples is available at CodeSandbox.

Basic Setup

This module exports a single function. Use this function to decorate your route definitions before passing them to vue-router:

import Vue from "vue";
import VueRouter from "vue-router";
import preload from "@badrap/preload";  // Import preload.
import Foo from "./Foo.vue";            // Import a couple of route components which
import Bar from "./Bar.vue";            // we decorate with preload.

Vue.use(VueRouter);

const routes = preload([                // Use preload here to decorate the route components...
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]);

const router = new VueRouter({ 
  routes                                // ...and pass them to vue-router.
});

new Vue({
  router,
  template: "<router-view />"
}).$mount("#app");

Adding Preloading to Components

After this setup dance the route components Foo and Bar can define a new method preload that is used to prepopulate their data whenever their route gets rendered - on initial render as well as route changes.

Let's define Foo in Foo.vue:

<template>
  <div>{{ greeting }}, {{ ip }}!</div>
</template>

<script>
import axios from "axios";

export default {
  async preload() {
    const { data } = await axios.get("https://api.ipify.org");
    return { ip: data };
  },
  data() {
    return { greeting: "Hello" };
  }
};
</script>

Rendering the route /foo would then show a div with the text "Hello, 127.0.0.1!", or whatever your IP address happens to be instead of 127.0.0.1. This demonstrates two things:

  • The properties returned by preload get combined with the properties returned by data.
  • preload can be asynchronous (it doesn't have to, though).

Context

The preload method gets a context object that contains useful information and helpers:

Context property Meaning
route The route object for the route that's currently being rendered.
redirect A function whose return value you can return from preload to redirect the router to. Takes a location descriptor.
error A function whose return value you can return from preload to signal a status error.

Here's an example that uses all of the above:

<script>
export default {
  async preload({ route, redirect, error }) {
    const { search } = route.query;
    if (!search) {
      return error(400, "?search= missing");
    }
    return redirect("https://google.com/search?q=" + encodeURIComponent(search));
  }
};
</script>

In addition to these properties you can mix in your own when decorating the route components:

const routes = preload(..., {
  context: {
    appName: "My sweet app"
  }
);

After this appName will be a part of every context object passed to preload methods of the decorated route components.

Hooks

In addition to extra context properties you can pass in two hooks. The beforePreload hook is executed before a route change causes preload methods to be called. The afterPreload hook gets executed when all of the preload calls are done.

const routes = preload(..., {
  beforePreload(() => {
    // Start a progress indicator here.
  }),
  afterPreload(err => {
    // Stop and hide the progress indicator here.
  })
);

Error Component

The default components that gets shown whenever preload returns a context.error(...) value can be replaced:

const routes = preload(..., {
  errorComponent: ErrorComponent
});

License

This library is licensed under the MIT license. See LICENSE.

You can’t perform that action at this time.