# 智能查询
在组件的 apollo
定义中声明的每个查询(不以 $
字符开头)都会创建一个智能查询对象。
# 选项
query
:GraphQL 文档(可以是一个文件或一个gql
字符串)。variables
:对象或返回对象的响应式函数。每个键将用'$'
映射到 GraphQL 文档中,例如foo
将变为$foo
。throttle
:变量更新节流时间(毫秒)。debounce
:变量更新防抖时间(毫秒)。pollInterval
:使用轮询自动更新的时间(表示每隔x
毫秒重新获取一次)。update(data) {return ...}
用来自定义设置到 vue 属性中的值,例如当字段名称不匹配时。result(ApolloQueryResult, key)
是收到结果时调用的钩子(更多参见 ApolloQueryResult (opens new window) 的文档)。key
是在apollo
选项中定义此查询时使用的键名。error(error, vm, key, type, options)
是出现错误时调用的钩子。error
是一个具有graphQLErrors
属性或networkError
属性的 Apollo 错误对象。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
是一个布尔值或一个返回布尔值的(响应式)函数。该函数的参数一个是当前组件,另一个是智能查询的键名,因此可以在$query
或是ApolloProvider
的defaultOptions
中使用。subscribeToMore
:一个或一组 subscribeToMore 选项 对象。prefetch
是一个布尔值或函数来确定是否应该预取查询。详见 服务端渲染。- 你还可以使用任意
watchQuery
的选项(参见 Apollo 文档 (opens new window))。
示例:
// Apollo 具体选项
apollo: {
// 带参数的高级查询
// vue 会侦听 'variables' 方法
pingMessage: {
query: gql`query PingMessage($message: String!) {
ping(message: $message)
}`,
// 响应式参数
variables () {
// 在这里使用 vue 的响应式属性
return {
message: this.pingInput,
}
},
// 轮询间隔,以毫秒为单位
pollInterval: 10000,
// 也可以通过 vue 响应式属性设置轮询间隔
pollInterval() {
return this.pollInterval;
},
// 变量:深度对象侦听
deep: false,
// 我们使用自定义的 update 回调函数,因为字段名称不匹配
// 默认情况下,将使用 'data' 结果对象上的 'pingMessage' 属性
// 考虑到 apollo 服务端的工作方式,我们知道结果是在 'ping' 属性中
update (data) {
console.log(data)
// 返回的值将更新 vue 属性 'pingMessage'
return data.ping
},
// 可选结果钩子
result ({ data, loading, networkStatus }) {
console.log('We got some result!')
},
// 错误处理
error (error) {
console.error('We\'ve got an error!', error)
},
// 加载状态
// loadingKey 是数据属性的名称
// 在查询正在加载时将递增,不再加载时递减
loadingKey: 'loadingQueriesCount',
// 当加载状态发生变化时会调用 watchLoading
watchLoading (isLoading, countModifier) {
// isLoading 是一个布尔值
// countModifier 为 1 或 -1
},
},
},
如果你使用 ES2015
,update
也可以这样写:
update: data => data.ping
手动模式示例:
{
query: gql`...`,
manual: true,
result ({ data, loading }) {
if (!loading) {
this.items = data.items
}
},
}
# 属性
# skip
你可以使用 skip
来暂停或停止暂停:
this.$apollo.queries.users.skip = true
# loading
查询是否正在加载中:
this.$apollo.queries.users.loading
# 方法
# refresh
停止并重新启动查询:
this.$apollo.queries.users.refresh()
# start
开始查询:
this.$apollo.queries.users.start()
# stop
停止查询:
this.$apollo.queries.users.stop()
# fetchMore
为分页加载更多数据:
this.page++
this.$apollo.queries.tagsPage.fetchMore({
// 新的变量
variables: {
page: this.page,
pageSize,
},
// 用新数据转换之前的结果
updateQuery: (previousResult, { fetchMoreResult }) => {
const newTags = fetchMoreResult.tagsPage.tags
const hasMore = fetchMoreResult.tagsPage.hasMore
this.showMoreEnabled = hasMore
return {
tagsPage: {
__typename: previousResult.tagsPage.__typename,
// 合并标签列表
tags: [...previousResult.tagsPage.tags, ...newTags],
hasMore,
},
}
},
})
# subscribeToMore
使用 GraphQL 订阅来订阅更多数据:
// 我们需要在重新订阅之前取消订阅
if (this.tagsSub) {
this.tagsSub.unsubscribe()
}
// 在查询上订阅
this.tagsSub = this.$apollo.queries.tags.subscribeToMore({
document: TAG_ADDED,
variables: {
type,
},
// 变更之前的结果
updateQuery: (previousResult, { subscriptionData }) => {
// 如果我们在没有做操作的情况下已经添加了标签
// 这可能是由 addTag 变更上的 `updateQuery` 导致
if (previousResult.tags.find(tag => tag.id === subscriptionData.data.tagAdded.id)) {
return previousResult
}
return {
tags: [
...previousResult.tags,
// 添加新的标签
subscriptionData.data.tagAdded,
],
}
},
})
# refetch
重新获取查询,可选择使用新变量:
this.$apollo.queries.users.refetch()
// 使用新变量
this.$apollo.queries.users.refetch({
friendsOf: 'id-user'
})
# setVariables
更新查询中的变量,如果发生了改变则重新获取查询。要强制重新获取,请使用 refetch
。
this.$apollo.queries.users.setVariables({
friendsOf: 'id-user'
})
# setOptions
更新 Apollo watchQuery (opens new window) 选项并重新获取:
this.$apollo.queries.users.setOptions({
fetchPolicy: 'cache-and-network'
})
# startPolling
使用轮询启动自动更新(这意味着每隔 x
ms 进行重新获取):
this.$apollo.queries.users.startPolling(2000) // ms
# stopPolling
停止轮询:
this.$apollo.queries.users.stopPolling()