點燈坊

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

如何將資料 Binding 到 GraphQL ?

Sam Xiao's Avatar 2019-10-25

Vue 在 HTML Template 的資料都會 Binding 到 data property 下,若想將該資料也 Binding 到 GraphQL 下該如何做呢 ?

Version

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

Vue Apollo

src/App.vue

<template>
  <div>
    <ul>
      <li v-for="(item, index) in books" :key="index">
        {{ item.title }}:{{ item.category }}
      </li>
    </ul>
  </div>
</template>

<script>
import gql from 'graphql-tag'

let books = function() {
  let query = gql`
    query ($category: BookCategory!) {
      books(category: $category) {
        title
        category
      }
    }
  `

  let variables = {
    category: this.category
  }

  return { query, variables }
}

export default {
  name: 'app',
  data: () => ({
    category: 'FP',
  }),
  apollo: {
    books
  }
}
</script>

34 行

export default {
  name: 'app',
  data: () => ({
    category: 'FP',
  }),
  apollo: {
    books
  }
}

apollo property 宣告 books query,我們希望以 data property 下的 category data 提供 books query 的 argument。

14 行

let books = function() {
  let query = gql`
    query ($category: BookCategory!) {
      books(category: $category) {
        title
        category
      }
    }
  `

  let variables = {
    category: this.category
  };

  return { query, variables }
};

要將 data property 下的資料 binding 到 GraphQL,最大的挑戰是 data 必須使用 this 去存取,因此 books 必須改用 function。

books query 使用 function,而非直接使用 GraphQL string,則要改回傳 object,而將 GraphQL 改放在 query property 下,因此可先定義 query variable,使用 ES6 的 property shorthand 產生 object 回傳,如此就能使用 this 存取 data property 下的資料。

binding000

Conclusion

  • 若要將資料 binding 到 GraphQL,則必須使用 query variable,然後 Vue 再將 data binding 到 variable
  • Vue Apollo 在 apollo 下的 property 有兩用,一是直接使用 GraphQL string,另一是使用 function,然後回傳包含 query property 的 object
  • 由於 Vue 一定要使用 this 存取 data,所以要改用 function,而不能直接使用 GraphQL string

Reference

Vue Apollo, Query with parameters