Last active
March 21, 2024 09:28
-
-
Save yann-yinn/5a8c00866872251e22ef8acf94188a9f to your computer and use it in GitHub Desktop.
Use "apollo-client" package with Vue.js, without "vue-apollo"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Example on how to create your own apolloClient. Just import this file from any of | |
// your component to begin to launch your graphql queries, mutations etc and that's it. | |
// Nothing more is needed, apolloClient by itself is already very powerful, without using vue-apollo. | |
// | |
// @see https://www.apollographql.com/docs/react/basics/setup.html | |
// @see https://www.apollographql.com/docs/react/api/apollo-client.html | |
import { ApolloClient } from 'apollo-client'; | |
import { createHttpLink } from 'apollo-link-http'; | |
import { InMemoryCache } from 'apollo-cache-inmemory'; | |
import { setContext } from 'apollo-link-context'; | |
import { getUser } from '@/app/lib/auth'; | |
const httpLink = createHttpLink({ | |
uri: process.env.VUE_APP_API_GRAPHQL_URL | |
}); | |
const authLink = setContext((_, { headers }) => { | |
// get the authentication token from local storage if it exists | |
const user = getUser(); | |
// return the headers to the context so httpLink can read them | |
return { | |
headers: { | |
...headers, | |
authorization: user.token ? `Bearer ${user.token}` : '' | |
} | |
}; | |
}); | |
const client = new ApolloClient({ | |
link: authLink.concat(httpLink), | |
cache: new InMemoryCache() | |
}); | |
export default client; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
If you really like to use apolloClient declaratively, here is a naive implementation | |
of a custom 'ApolloQuery' component | |
--> | |
<template> | |
<div> | |
<slot name="result" :result="this.result" /> | |
</div> | |
</template> | |
<script> | |
import apolloClient from '@/app/lib/apolloClient'; | |
export default { | |
data() { | |
return { | |
// some default values until query begin | |
result: { | |
data: null, | |
loading: false, | |
networkStatus: 7, | |
error: null | |
} | |
}; | |
}, | |
props: { | |
query: { | |
type: Object, | |
required: true | |
}, | |
variables: { | |
type: Object, | |
required: true | |
}, | |
options: { | |
type: Object, | |
default: () => ({}) | |
} | |
}, | |
methods: { | |
// you can call this method from outside of the component, using "ref" attribute | |
// This is might be useful to relaunch the query after a mutation happened in the parent | |
apolloQuery(variables = {}, options = {}) { | |
this.result.loading = true; | |
return apolloClient | |
.query({ | |
...this.options, | |
...options, | |
query: this.query, | |
variables: { | |
...this.variables, | |
...variables | |
} | |
}) | |
.then(result => { | |
this.result = result; | |
}) | |
.catch(error => { | |
this.result.error = error; | |
}); | |
} | |
}, | |
created() { | |
this.apolloQuery(); | |
}, | |
watch: { | |
variables: { | |
deep: true, | |
handler: function() { | |
this.apolloQuery(); | |
} | |
} | |
} | |
}; | |
</script> | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
This is an example on how to call declaratively | |
apolloClient with a custom ApolloQuery component | |
@see ApolloQuery.vue in this Gist | |
--> | |
<template> | |
<div> | |
<ApolloQuery :query="query" :variables="queryVariables"> | |
<template #result="{ result: { data, loading, error } }"> | |
<div v-if="loading">Loading</div> | |
<div v-if="error">{{ error }}</div> | |
<div v-if="data">{{ data }}</div> | |
</template> | |
</ApolloQuery> | |
</div> | |
</template> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
import apolloClient from '@/app/lib/apolloClient'; | |
// here is an example on how to call manually "apolloClient" from one of your component | |
export default { | |
data() { | |
return { | |
result: null, | |
error: null, | |
state: 'NOT_STARTED' | |
} | |
}, | |
created() { | |
this.state = 'PENDING'; // state to use to display a loading message | |
apolloClient | |
.query({ | |
query: yourQuery, | |
variables: { | |
id | |
} | |
}) | |
.then(result => { | |
this.result = result; | |
this.state = 'FINISHED_OK'; | |
}) | |
.catch(error => { | |
this.error = error; | |
this.state = 'FINISHED_ERROR' | |
}); | |
} | |
} | |
} | |
</script> |
Thank you so much, this is exactly what I want. Make life a lot easier with less magic tricks
@davyzhang glad it helped.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I will try this today and see if it works for my use cases.