跳至内容

响应式查询

在组件中,每个在 apollo 定义中声明的查询(即,不以 $ 字符开头的查询)都会创建一个响应式查询对象。

选项

  • query: GraphQL 文档(可以是文件或 gql 字符串)。
  • variables: 对象或返回对象的响应式函数。每个键都将在 GraphQL 文档中映射为 '$',例如 foo 将变为 $foo
  • throttle: 节流变量更新(以毫秒为单位)。
  • debounce: 防抖变量更新(以毫秒为单位)。
  • pollInterval: 使用轮询自动更新(这意味着每 x 毫秒重新获取一次)。默认值:undefined0 - 停止轮询。或者,这可以是一个返回轮询间隔的响应式函数。返回 null 以停止轮询。
  • update(data) {return ...} 用于自定义在 vue 属性中设置的值,例如,如果字段名称不匹配。
  • result(ApolloQueryResult, key) 是在收到结果时调用的钩子(有关 ApolloQueryResult 的文档)。keyapollo 选项中的查询键。
  • error(error, vm, key, type, options) 是在出现错误时调用的钩子。error 是一个 Apollo 错误对象,它具有 graphQLErrors 属性或 networkError 属性。vm 是相关的组件实例。key 是响应式查询键。type'query''subscription'options 是最终的 watchQuery 选项对象。
  • loadingKey 将更新您作为值传递的组件数据属性。您应该在组件 data() 钩子中将此属性初始化为 0。当查询正在加载时,此属性将增加 1;当它不再加载时,它将减少 1。这样,该属性可以表示当前正在加载的查询计数器。
  • watchLoading(isLoading, countModifier) 是在查询的加载状态发生变化时调用的钩子。countModifier 参数在查询正在加载时等于 1,在查询不再加载时等于 -1
  • manual 是一个布尔值,用于禁用自动属性更新。如果您使用它,则需要指定 result 回调(请参阅下面的示例)。
  • deep 是一个布尔值,用于在 Vue 观察者上使用 deep: true
  • skip 是一个布尔值或返回布尔值的(响应式)函数。该函数获取当前组件和响应式查询键作为参数,因此它可以在 $queryApolloProviderdefaultOptions 中使用。
  • subscribeToMore: 一个对象或一个对象数组,它们是 subscribeToMore 选项
  • prefetch 是一个布尔值或一个函数,用于确定是否应该预取查询。请参阅 服务器端渲染
  • 您还可以使用任何其他 watchQuery 选项(请参阅 Apollo 文档)。

示例

js
// Apollo-specific options
apollo: {
  // Advanced query with parameters
  // The 'variables' method is watched by vue
  pingMessage: {
    query: gql`query PingMessage($message: String!) {
      ping(message: $message)
    }`,
    // Reactive parameters
    variables () {
      // Use vue reactive properties here
      return {
        message: this.pingInput,
      }
    },
    // Polling interval in milliseconds
    pollInterval: 10000,
    // Or, set polling interval as a vue reactive property
    pollInterval() {
      return this.pollInterval;
    },
    // Variables: deep object watch
    deep: false,
    // We use a custom update callback because
    // the field names don't match
    // By default, the 'pingMessage' attribute
    // would be used on the 'data' result object
    // Here we know the result is in the 'ping' attribute
    // considering the way the apollo server works
    update (data) {
      console.log(data)
      // The returned value will update
      // the vue property 'pingMessage'
      return data.ping
    },
    // Optional result hook
    result ({ data, loading, networkStatus }) {
      console.log('We got some result!')
    },
    // Error handling
    error (error) {
      console.error('We\'ve got an error!', error)
    },
    // Loading state
    // loadingKey is the name of the data property
    // that will be incremented when the query is loading
    // and decremented when it no longer is.
    loadingKey: 'loadingQueriesCount',
    // watchLoading will be called whenever the loading state changes
    watchLoading (isLoading, countModifier) {
      // isLoading is a boolean
      // countModifier is either 1 or -1
    },
  },
},

如果您使用 ES2015,您也可以这样编写 update

js
update: data => data.ping

手动模式示例

js
{
  query: gql`...`,
  manual: true,
  result ({ data, loading }) {
    if (!loading) {
      this.items = data.items
    }
  },
}

属性

skip

您可以使用 skip 暂停或取消暂停

js
this.$apollo.queries.users.skip = true

loading

查询是否正在加载

js
this.$apollo.queries.users.loading

方法

refresh

停止并重新启动查询

js
this.$apollo.queries.users.refresh()

start

启动查询

js
this.$apollo.queries.users.start()

stop

停止查询

js
this.$apollo.queries.users.stop()

fetchMore

加载更多数据以进行分页

js
this.page++

this.$apollo.queries.tagsPage.fetchMore({
  // New variables
  variables: {
    page: this.page,
    pageSize,
  },
  // Transform the previous result with new data
  updateQuery: (previousResult, { fetchMoreResult }) => {
    const newTags = fetchMoreResult.tagsPage.tags
    const hasMore = fetchMoreResult.tagsPage.hasMore

    this.showMoreEnabled = hasMore

    return {
      tagsPage: {
        __typename: previousResult.tagsPage.__typename,
        // Merging the tag list
        tags: [...previousResult.tagsPage.tags, ...newTags],
        hasMore,
      },
    }
  },
})

subscribeToMore

使用 GraphQL 订阅订阅更多数据

js
// We need to unsubscribe before re-subscribing
if (this.tagsSub) {
  this.tagsSub.unsubscribe()
}
// Subscribe on the query
this.tagsSub = this.$apollo.queries.tags.subscribeToMore({
  document: TAG_ADDED,
  variables: {
    type,
  },
  // Mutate the previous result
  updateQuery: (previousResult, { subscriptionData }) => {
    // If we added the tag already don't do anything
    // This can be caused by the `updateQuery` of our addTag mutation
    if (previousResult.tags.find(tag => tag.id === subscriptionData.data.tagAdded.id)) {
      return previousResult
    }

    return {
      tags: [
        ...previousResult.tags,
        // Add the new tag
        subscriptionData.data.tagAdded,
      ],
    }
  },
})

refetch

再次获取查询,可以选择使用新变量

js
this.$apollo.queries.users.refetch()
// With new variables
this.$apollo.queries.users.refetch({
  friendsOf: 'id-user'
})

setVariables

更新查询上的变量,如果它们已更改,则重新获取。要强制重新获取,请使用 refetch

js
this.$apollo.queries.users.setVariables({
  friendsOf: 'id-user'
})

setOptions

更新 Apollo watchQuery 选项并重新获取

js
this.$apollo.queries.users.setOptions({
  fetchPolicy: 'cache-and-network'
})

startPolling

使用轮询启动自动更新(这意味着每 x 毫秒重新获取一次)

js
this.$apollo.queries.users.startPolling(2000) // ms

stopPolling

停止轮询

js
this.$apollo.queries.users.stopPolling()