點燈坊

失くすものさえない今が強くなるチャンスよ

使用 Vue Apollo 建立 Mutation

Sam Xiao's Avatar 2019-10-29

GraphQL 除了使用 Query 查詢資料外,若要異動資料,包含新增、修改、刪除,都要使用 Mutation。

Version

macOS Catalina 10.15
WebStorm 2019.2.3
Node 10.16.3
Vue CLI 4.0.5
Vue 2.6.10
Vue Apollo 3.0.0-beta.11

Vue Apollo

src/App.vue

<template>
  <div>{{ book.title }} / {{ book.price }}</div>
</template>

<script>
import gql from 'graphql-tag'

let mutation = gql`
  mutation {
    addBook(book: {
      title: "Speaking JavaScript"
      price: 300
    }) {
      title
      price
   }
  }
`

let mounted = function() {
  this.$apollo.mutate({ mutation })
    .then(({ data: { addBook } }) => this.book = addBook)
}

export default {
  name: 'app',
  data: () => ({
    book: {}
  }),
  mounted
}
</script>

25 行

export default {
  name: 'app',
  data: () => ({
    book: {}
  }),
  mounted
}

books data 為 addBook mutation 的回傳值,所有執行 mutation 動作將寫在 mounted hooks 內。

20 行

let mounted = function() {
  this.$apollo.mutate({ mutation })
    .then(({ data: { addBook } }) => this.book = addBook)
}

Mutation 必須使用 this.$apollo.mutate() 執行,傳入以 mutation 為 property 的 object,沒有所謂 smart mutation。

mutate() 回傳為 promise,可在 then() 的 callback 直接 object destructuring 解構出 mutation 回傳資料,最後以 side effect 寫入 book data。

let mounted = async function() {
  let { data: { addBook }} = await this.$apollo.mutate({ mutation })
  this.book = addBook
}

也可以使用 await 處理 mutate() 回傳 promise,最後依然以 object destructuring 解構。

第 8 行

let mutation = gql`
  mutation {
    addBook(book: {
      title: "Speaking JavaScript"
      price: 300
    }) {
      title
      price
   }
  }
`

使用 mutation 定義 GraphQL mutation。

mutation000

Vue 顯示 GraphQL mutation 所回傳的資料。

Conclusion

  • Vue Apollo 無法使用 declarative 方式使用 mutation,必須改用 this.$apollo.mutate() 動態建立 mutation
  • 若要取得 mutation 回傳資料,或者在 mutation 執行完之後重新執行另一個 query,因為 mutate() 回傳 promise,可繼續使用 then()await
  • 由於 this.$apollo.mutate() 回傳為 promise,因此使用 then()await 處理 mutation 回傳資料皆可。

Sample Code

完整範例可在我的 GitHub 上找到

Reference

Vue Apollo, Mutations