# ApolloQuery
Vous pouvez utiliser le composant ApolloQuery
(ou apollo-query
) pour avoir des requĂȘtes Apollo observĂ©es directement dans vos templates.
AprÚs avoir lu cette page, consultez la référence API pour connaßtre toutes les options disponibles.
# Le gabarit étiqueté gql
C'est la méthode recommandée pour utiliser le composant ApolloQuery
. Il utilise la mĂȘme syntaxe avec le gabarit Ă©tiquetĂ© gql
que dans les autres exemples :
<template>
<ApolloQuery
:query="gql => gql`
query MyHelloQuery ($name: String!) {
hello (name: $name)
}
`"
:variables="{ name }"
>
<!-- TODO -->
</ApolloQuery>
</template>
Nous passons une fonction Ă la prop query
qui prent le gabarit gql
en argument, afin de pouvoir le document GraphQL directement.
L'exemple ci-dessus passe Ă©galement variables
Ă la requĂȘte en utilisant la prop du mĂȘme nom.
Dans le slot par défaut d'ApolloQuery
, vous pouvez accĂ©der Ă de la donnĂ©e concernant la requĂȘte observĂ©e, comme par exemple l'object result
:
<template v-slot="{ result: { loading, error, data } }">
<!-- Chargement -->
<div v-if="loading" class="loading apollo">Chargement...</div>
<!-- Erreur -->
<div v-else-if="error" class="error apollo">Une erreur est survenue.</div>
<!-- RĂ©sultat -->
<div v-else-if="data" class="result apollo">{{ data.hello }}</div>
<!-- Pas de résultat -->
<div v-else class="no-result apollo">Pas de résultat :(</div>
</template>
Voici un exemple complet :
<script>
export default {
data () {
return {
name: 'Anne'
}
}
}
</script>
<template>
<div>
<input v-model="name" placeholder="Renseignez votre nom">
<ApolloQuery
:query="gql => gql`
query MyHelloQuery ($name: String!) {
hello (name: $name)
}
`"
:variables="{ name }"
>
<template v-slot="{ result: { loading, error, data } }">
<!-- Chargement -->
<div v-if="loading" class="loading apollo">Chargement...</div>
<!-- Erreur -->
<div v-else-if="error" class="error apollo">Une erreur est survenue.</div>
<!-- RĂ©sultat -->
<div v-else-if="data" class="result apollo">{{ data.hello }}</div>
<!-- Pas de résultat -->
<div v-else class="no-result apollo">No result :(</div>
</template>
</ApolloQuery>
</div>
</template>
# Mise en place du gabarit étiqueté
Si vous n'utilisez pas vue-cli-plugin-apollo (opens new window) (v0.20.0+
), vous devez configurer vue-loader (opens new window) pour transpiler le gabarit étiqueté. vue-loader
utilise Bublé (opens new window) sous le capot pour transpiler le code dans les templates des composants. Nous devons ajouter la transformation dangerousTaggedTemplateString
à Bublé pour que gql
fonctionne. Par exemple, avec Vue CLI :
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
options.transpileOptions = {
transforms: {
dangerousTaggedTemplateString: true,
},
}
return options
})
}
}
Dans une configuration Webpack de base, ça ressemblerait à ça :
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
use: [
{
loader: 'vue-loader',
options: {
transpileOptions: {
transforms: {
dangerousTaggedTemplateString: true
}
}
}
}
]
},
/* D'autres rĂšgles... */
]
}
}
# RequĂȘter avec des fichiers gql
Une façon alternative d'utiliser le composant est de créer des fichirs .gql
sĂ©parĂ©s. Ces fichiers doivent ĂȘtre prĂ©-trasnformĂ©s avec graphql-tag (opens new window).
<template>
<ApolloQuery
:query="require('../graphql/HelloWorld.gql')"
:variables="{ name }"
>
<template v-slot="{ result: { loading, error, data } }">
<!-- Chargement -->
<div v-if="loading" class="loading apollo">Chargement...</div>
<!-- Erreur -->
<div v-else-if="error" class="error apollo">Une erreur est survenue.</div>
<!-- RĂ©sultat -->
<div v-else-if="data" class="result apollo">{{ data.hello }}</div>
<!-- Pas de résultat -->
<div v-else class="no-result apollo">Pas de résultat :(</div>
</template>
</ApolloQuery>
</template>
# OpĂ©rations de requĂȘte
Vous pouvez accĂ©der Ă l'object de requĂȘte intelligent avec le prop de slot query
. Voici un composant d'exemple qui pagine des données en utilisant fetchMore
:
<template>
<ApolloQuery
:query="/* requĂȘte */"
:variables="{
limit: $options.pageSize
}"
v-slot="{ result: { loading, error, data }, query }"
>
<!-- Affichage des données -->
<button v-if="hasMore" @click="loadMore(query)">Charger plus</button>
</ApolloQuery>
</template>
<script>
export default {
pageSize: 10,
data: {
return {
page: 1,
hasMore: true
}
},
methods: {
async loadMore (query) {
await query.fetchMore({
variables: {
offset: this.page++ * this.$options.pageSize
},
updateQuery: (prev, { fetchMoreResult }) => {
if (!fetchMoreResult || fetchMoreResult.product.length === 0) {
this.hasMore = false
return prev
}
return Object.assign({}, prev, {
product: [...prev.product, ...fetchMoreResult.product]
})
}
})
}
}
}
</script>
Consultez la rĂ©fĂ©rence API pour connaĂźtre toutes les mĂ©thodes de requĂȘte intelligentes.
# Utiliser des fragments
Les fragments sont intĂ©ressants pour partager des morceaux de documents GraphQL dans d'autres documents pour rĂ©cupĂ©rer la mĂȘme donnĂ©e de façon uniforme, et Ă©viter de dupliquer du code.
Imaginons que nous avons une requĂȘte GetMessages
avec un champ messages
qui est un tableau d'objets Message
:
query GetMessages {
messages {
id
user {
id
name
}
text
created
}
}
Nous voulons extraire tous les champs de messages
qui ont le type Message
dans un fragment, pour pouvoir les réutiliser ailleurs.
D'abord, importez le gabarit gql
dans le composant :
import gql from 'graphql-tag'
Puis, dans la définition du composant, déclarez un nouvel objet fragments
:
export default {
fragments: {
/** TODO */
}
}
Voici Ă quoi le fragment message
, qui est appliqué au type Message
, ressemble :
fragment message on Message {
id
user {
id
name
}
text
created
}
Nous pouvons utiliser le gabarit gql
comme avec les requĂȘtes :
export default {
fragments: {
message: gql`
fragment message on Message {
id
user {
id
name
}
text
created
}
`
}
}
Dans notre composant, nous pouvons maintenant accéder au fragment grùce à this.$options.fragments.message
. Pour utiliser ce fragmnt dans notre requĂȘte GetMessages
, nous devons utiliser la syntaxe de décomposition de GraphQL (...
), ainsi que d'ajouter le fragment avec la requĂȘte :
gql`
query GetMessages {
messages {
...message
}
}
${$options.fragments.message}
`
Cela produira le document GraphQL (que vous pouvez essayer dans l'environnement de test de GraphQL de votre API) :
query GetMessages {
messages {
...message
}
}
fragment message on Message {
id
user {
id
name
}
text
created
}
Que se passe-t-il ici ? GraphQL trouve l'opérateur ...
oĂč l'on sĂ©lectionne des champs dans le champ messages
Ă l'intĂ©rieur de notre requĂȘte. L'opĂ©rateur ...
est suivi par le nom du fragment, message
, qui est ensuite recherchĂ© dans tout le document GraphQL. Nous avons correctement dĂ©fini le fragment, que nous trouvons juste aprĂšs la requĂȘte. Enfin, GraphQL copie tout le contenu du fragment et remplace ...message
avec.
On obtient la requĂȘte finale :
query GetMessages {
messages {
id
user {
id
name
}
text
created
}
}
fragment message on Message {
id
user {
id
name
}
text
created
}
Voici le composant d'exemple complet :
<!-- MessageList.vue -->
<script>
import gql from 'graphql-tag'
export default {
fragments: {
message: gql`
fragment message on Message {
id
user {
id
name
}
text
created
}
`
}
}
</script>
<template>
<ApolloQuery
:query="gql => gql`
query GetMessages {
messages {
...message
}
}
${$options.fragments.message}
`"
>
<!-- Contenu... -->
</ApolloQuery>
</template>
# RĂ©utiliser le fragment
Nous pouvons désormais récupérer le fragment message
dans d'autres composants :
<!-- MessageForm.vue -->
<script>
import gql from 'graphql-tag'
import MessageList from './MessageList.vue'
export default {
methods: {
async sendMessage () {
await this.$apollo.mutate({
mutation: gql`
mutation SendMessage ($input: SendMessageInput!) {
addMessage (input: $input) {
newMessage {
...message
}
}
}
${MessageList.fragments.message}
`,
variables: {
/* Variables */
},
/* Autres options */
})
}
}
}
</script>