January 11, 2022

Getting Started with Vue Apollo

Khalil Stemmler

Khalil Stemmler

Introduction

Vue is a modern JavaScript framework for building single-page applications. Apollo Client is a fully-fledged GraphQL client and state management library. Using Vue Apollo, we can combine them to substantially improve the developer experience involved in building complex UIs.

In this article, we’ll learn how to get started building with Vue, GraphQL, and Apollo Client using the latest versions of Apollo Client and Vue Apollo.

Prerequisites

Before we get started, this article assumes:

Options vs. Composition API

We should start by first discussing In 2021, there are two ways to use Vue Apollo. We can use either the:

The Options API is based on the original apollo Vue component definition. It used the standard syntax for Vue 2, object structure to define queries, and requires additional logic for error state. In practice, it looks something like this:

<script>
export default {
  apollo: {
    // Queries here
  }
}
</script>

The newer Composition API, however, provides better abstractions for code reuse, scales better than the classic Options API, and will feel familiar to developers coming from a background using React hooks or Apollo’s useQuery and useMutation API.

Additional reading: You can read more about the Composition API here.

Since the maintainers plan to prioritize the Composition API in the future, we’re going to tailor this tutorial towards that one.

Setup

Installing the Vue CLI

To begin, let’s install the Vue CLI. It’s a command-line tool that gives you loads of customizability for starting a new project.

npm install -g @vue/cli

Create a new Vue app

Next, we’ll use the Vue CLI to create a new project. Let’s call it app.

vue create app

Once you enter the command, you’ll be presented with a number of different configuration options for your project.

For this tutorial, we just selected the second option to use Vue 3. However, if you’d like to use TypeScript, add or remove linting, add unit and E2E testing features, you can select Manually select features. Make sure to use Vue version 3.

This should take a moment to install.

Installing the base dependencies

Once you’ve set up your project, we’ll want to move into the project folder and npm install some base dependencies.

cd app
npm install --save graphql graphql-tag @apollo/client

Installing the Composition API

Here’s the point where if we wanted to use the classic Options API, we could go down a different configuration road. But since we’re going to use the Composable API, we’ll npm install that now with the following command.

npm install --save @vue/apollo-composable

Starting the app

To start the app, run npm run server and then go to localhost:8080.

npm run serve

If all went correctly, you should see the Vue getting started page.

Now let’s configure Vue Apollo so that we can fetch GraphQL data.

Initial Vue Apollo config

For this tutorial, we’re going to use the Rick & Morty API to demonstrate the basics. Inside of the main.js file, copy and paste the following setup code to configure Vue Apollo and Apollo client in your Vue app.

// main.js

import { createApp, provide, h } from 'vue'
import { DefaultApolloClient } from '@vue/apollo-composable'
import { ApolloClient, InMemoryCache } from '@apollo/client/core'
import App from './App.vue'

const cache = new InMemoryCache()

const apolloClient = new ApolloClient({
  cache,
  uri: '<https://rickandmortyapi.com/graphql>',
})

const app = createApp({
  setup () {
    provide(DefaultApolloClient, apolloClient)
  },

  render: () => h(App),
})

app.mount('#app');


Next, let’s head over the main App.vue so that we can query some data.

Querying data

In the script section of your App.vue Vue single-file component, we’re going to start by writing a query to fetch a list of characters from the Rick & Morty API.

// <script>

import gql from 'graphql-tag'

const CHARACTERS_QUERY = gql`
  query Characters {
    characters {
      results {
        id
        name
        image
      }
    }
  }
`
...

// </script>


Next, we’re going to import useQuery from @vue/apollo-composable and pass our query to it within a setup function on the object we export.

Make sure to decompose the return value of useQuery into result, loading and error values so that we can utilize them within our template.

// <script>
import gql from 'graphql-tag'
import { useQuery } from '@vue/apollo-composable'

...

export default {
  name: 'App',
  setup () {
    const { result, loading, error } = useQuery(CHARACTERS_QUERY);
    return {
      result,
      loading, 
      error
    }
  }
}
// </script>

Finally, at the top of the file within our Vue template, we can perform conditional rendering using the v-if directive.

<template>
  <p v-if="error">Something went wrong...</p>
  <p v-if="loading">Loading...</p>
  <p v-else v-for="character in result.characters.results" :key="character.id">
    {{ character.name }}
  </p>
  <div></div>
</template>

If the value of error is defined, we’ll print out “Something went wrong…”

If the value of loading is true, we’ll be sure to print “Loading”.

And using the v-else directive, if loading is false, we’ll map over the characters using the v-for directive, making sure to let Vue know how to uniquely identify items with the :key directive.

If we’ve configured this correctly, we should see a list of characters.

Our final App.vue should look something like the following:

<template>
  <p v-if="error">Something went wrong...</p>
  <p v-if="loading">Loading...</p>
  <p v-else v-for="character in result.characters.results" :key="character.id">
    {{ character.name }}
  </p>
  <div></div>
</template>

<script>
import gql from 'graphql-tag'
import { useQuery } from '@vue/apollo-composable'

const CHARACTERS_QUERY = gql`
  query Characters {
    characters {
      results {
        id
        name
        image
      }
    }
  }
`

export default {
  name: 'App',
  setup () {
    const { result, loading, error } = useQuery(CHARACTERS_QUERY);
    return {
      result,
      loading, 
      error
    }
  }
}

</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>


What next?

We just learned how to set up a Vue Apollo app and how to query a GraphQL server using the Vue Composition API.

I recommend continuing by reading the composition API docs. With respect to the topic of queries:

With respect to mutations:

Also be sure to learn about subscriptions, pagination, and error-handling in Vue Apollo.

For a video walkthrough and more information on the difference between the Options API vs. the Composition one, check out Natalia Tepluhina’s talk from GraphQL Summit Worldwide 2021.

Written by

Khalil Stemmler

Khalil Stemmler

Read more by Khalil Stemmler