Use Apollo in your VueJS app
Guillaume Chau
Editor’s note: This post is from Guillaume Chau, an Apollo contributor who built an integration package between VueJS and Apollo. Check it out and contribute to it here!
As you may know, the Apollo team has built a great GraphQL client and tooling that makes it easy to use data from your server in any JavaScript app. Why not use it with another amazing technology like VueJS?
Now you can do just that with vue-apollo, an npm package I wrote that allows you to write GraphQL queries in your VueJS components while using Apollo under the hood.
Use it in your VueJS app
First, install these packages in your project folder:
npm install — save apollo-client vue-apollo
Then, you need to create an Apollo client and install the vue-apollo plugin into VueJS:
import Vue from 'vue';
import App from './App.vue';
import ApolloClient, { createNetworkInterface, addTypename } from 'apollo-client';
import VueApollo from 'vue-apollo';
// Create the apollo client
const apolloClient = new ApolloClient({
networkInterface: createNetworkInterface({
uri: 'http://localhost:8080/graphql',
transportBatching: true,
}),
queryTransformer: addTypename,
dataIdFromObject: r => r.id,
});
// Install the vue plugin
// With the apollo client instance
Vue.use(VueApollo, {
apolloClient,
});
// Start the Vue app
new Vue({
el: '#app',
render: h => h(App)
});
Fetch data with GraphQL queries
You can now use Apollo directly in your components to query your GraphQL server. Inside a component, the Apollo client can be accessed with ‘this.$apollo’:
<script>
export default {
created() {
this.$apollo.watchQuery({
/* options */
}).then(data => {
console.log(data);
});
},
};
</script>
But the preferred way to make queries is to declare them with the ‘apollo’ option in the component definition:
<script>
import gql from 'graphql-tag';
// GraphQL query
const postsQuery = gql`
query allPosts {
posts {
id
title
votes
author {
id
firstName
lastName
}
}
}
`;
// Vue component definition
export default {
// Local state
data: () => ({
// You can initialize the 'posts' data here
posts: [],
loading: 0,
}),
// Apollo GraphQL
apollo: {
// Local state 'posts' data will be updated
// by the GraphQL query result
posts: {
// GraphQL query
query: postsQuery,
// Will update the 'loading' attribute
// +1 when a new query is loading
// -1 when a query is completed
loadingKey: 'loading',
},
},
};
</script>
<template>
<div class="post-list">
<!-- If there is one or more queries loading -->
<template v-if="loading > 0">
Loading
</template>
<!-- Actual view -->
<template v-else>
<ul>
<!-- Post list items -->
<li v-for="post in posts" :key="post.id">
{{ post.title }} by
{{ post.author.firstName }} {{ post.author.lastName }}
</li>
</ul>
</template>
</div>
</template>
Thanks to the VueJS reactivity system, the ‘posts’ local data will be automatically updated with the GraphQL query result and your DOM updated.
You can initialize the corresponding data attribute in the ‘data’ hook with a default value:
// Local state
data: () => ({
// You can initialize the 'posts' data here
posts: [],
loading: 0,
}),
If you want to update your data automatically when another user changes it, you can poll the server with the ‘pollInterval’ option, specifying an interval duration in milliseconds:
apollo: {
posts: {
query: postsQuery,
loadingKey: 'loading',
// Polling query
pollInterval: 300, // ms
},
},
Update your data with GraphQL mutations
In the component methods and hooks, you can use the ‘$apollo’ object to call mutations:
<script>
import gql from 'graphql-tag';
// GraphQL Mutation with one parameter
const upvoteMutation = gql`
mutation upvotePost($postId: Int!) {
upvotePost(postId: $postId) {
id
votes
}
}
`;
export default {
// Attribute
props: {
// Post id passed down to this component
postId: {
type: Number,
required: true,
},
},
methods: {
upvote() {
// Mutation
this.$apollo.mutate({
mutation: upvoteMutation,
variables: {
postId: this.postId,
},
}).then(data => {
console.log('Done upvoting.');
});
},
},
};
</script>
<template>
<button @click="upvote">Upvote</button>
</template>
In this component, we call the ‘upvotePost’ mutation on the GraphQL server, that returns the updated post data. That way, the Apollo cache is up-to-date, and again, thanks to VueJS reactivity system, your view should reflect the new votes count.
These are just the basics of using Apollo in your VueJS components. The more advanced features in vue-apollo are documented here, and you can take a look at the hello world example to have a better idea of how things work.