跳至内容

ApolloMutation

您可以使用 ApolloMutation(或 apollo-mutation)组件直接在您的模板中调用 Apollo 变异。

以下是一个示例

vue
<ApolloMutation
  :mutation="gql => gql`
    mutation DoStuff ($name: String!) {
      someWork (name: $name) {
        success
        timeSpent
      }
    }
  `"
  :variables="{
    name
  }"
  @done="onDone"
>
  <template v-slot="{ mutate, loading, error }">
    <button :disabled="loading" @click="mutate()">Click me</button>
    <p v-if="error">An error occurred: {{ error }}</p>
  </template>
</ApolloMutation>

请参阅 ApolloQuery 了解如何在模板中编写 GraphQL 查询。

请参阅 API 参考 以获取所有可用选项。

更新缓存

如果变异仅更新您已经在缓存中拥有的对象(例如,编辑现有字段),则您无需执行任何操作,因为 Apollo Client 会自动更新缓存。这仅在变异结果中的对象包含 __typenameid 字段(或您用于 规范化缓存 的自定义字段)时有效。

否则,您需要告诉 Apollo Client 如何使用变异结果更新缓存。例如,如果变异添加了一个新项目,您必须更新相关的查询结果以有效地将此新项目推送到查询中。

添加项目

vue
<template>
  <ApolloMutation
    :mutation="gql => gql`
      mutation ($input: SendMessageToThreadInput!) {
        sendMessageToThread (input: $input) {
          message {
            ...message
          }
        }
      }
      ${$options.fragments.message}
    `"
    :variables="{
      threadId,
      text
    }"
    :update="updateCache"
  >
    <!-- Form here -->
  </ApolloMutation>
</template>

<script>
import gql from 'gql-tag'

const fragments = {
  message: gql`
    fragment message on Message {
      id
      text
      user {
        id
        name
      }
    }
  `
}

export default {
  fragments,

  props: {
    threadId: {
      type: String,
      required: true
    }
  },

  methods: {
    updateCache (store, { data: { sendMessageToThread } }) {
      const query = {
        query: gql`
        query ($threadId: ID!) {
          thread (id: $threadId) {
            id
            messages {
              ...message
            }
          }
        }
        ${fragments.message}
        `,
        variables: {
          threadId: this.threadId,
        },
      }
      // Read the query from cache
      let data = store.readQuery(query)
      // Change cache result
      data = {
        ...data,
        thread: {
          ...data.thread,
          messages: [
            ...data.thread.messages,
            sendMessageToThread.message
          ],
        },
      }
      // Write back to the cache
      store.writeQuery({
        ...query,
        data,
      })
    },
  }
}
</script>

删除项目

vue
<template>
  <ApolloMutation
    :mutation="gql => gql`
      mutation ($input: DeleteMessageFromThreadInput!) {
        deleteMessageFromThread (input: $input) {
          success
        }
      }
    `"
    :variables="{
      threadId,
      messageId
    }"
    :update="updateCache"
  >
    <!-- Form here -->
  </ApolloMutation>
</template>

<script>
import gql from 'gql-tag'

const fragments = {
  message: gql`
    fragment message on Message {
      id
      text
      user {
        id
        name
      }
    }
  `
}

export default {
  fragments,

  props: {
    threadId: {
      type: String,
      required: true
    },
    messageId: {
      type: String,
      required: true
    }
  },

  methods: {
    updateCache (store, { data: { deleteMessageFromThread } }) {
      const query = {
        query: gql`
        query ($threadId: ID!) {
          thread (id: $threadId) {
            id
            messages {
              ...message
            }
          }
        }
        ${fragments.message}
        `,
        variables: {
          threadId: this.threadId,
        },
      }
      // Read the query from cache
      let data = store.readQuery(query)
      // Change cache result
      data = {
        ...data,
        thread: {
          ...data.thread,
          messages: data.thread.messages.filter(m => m.id !== this.messageId),
        },
      }
      // Write back to the cache
      store.writeQuery({
        ...query,
        data,
      })
    },
  }
}
</script>