跳至内容

查询

在 GraphQL 中,查询是向 API 发出的检索数据的请求。它用GraphQL 文档表示,如下所示

graphql
query myHelloQueryName {
  hello
}

apollo对象中,为每个要使用 Apollo 查询结果填充的属性添加一个属性。它们中的每一个都将成为一个智能查询

智能查询是围绕 GraphQL 查询的包装器,具有自动响应性等附加功能。

简单查询

使用gql编写 GraphQL 查询

js
import gql from 'graphql-tag'

gql查询直接作为值放入

js
apollo: {
  // Simple query that will update the 'hello' vue property
  hello: gql`query {
    hello
  }`,
},

然后,您可以使用this.$apollo.queries.<name>访问智能查询。

您可以在 Vue 组件的data钩子中初始化属性

js
data () {
  return {
    // Initialize your apollo data
    hello: '',
  },
},

在服务器端,添加相应的模式和解析器

js
export const schema = `
type Query {
  hello: String
}

schema {
  query: Query
}
`

export const resolvers = {
  Query: {
    hello (root, args, context) {
      return 'Hello world!'
    },
  },
}

有关更多信息,请访问apollo 文档

然后,您可以在 Vue 组件中照常使用您的属性

vue
<template>
  <div class="apollo">
    <h3>Hello</h3>
    <p>
      {{hello}}
    </p>
  </div>
</template>

名称匹配

请注意,常见的初学者错误是使用与查询中字段名称不同的数据名称,例如

js
apollo: {
  world: gql`query {
    hello
  }`
}

注意worldhello不同;vue-apollo不会从查询结果中猜测您要放入组件中的数据。默认情况下,它只会尝试您在组件中用于数据的名称(即apollo对象中的键),在本例中为world。如果名称不匹配,您可以使用update选项告诉vue-apollo从结果中使用什么作为数据

js
apollo: {
  world: {
    query: gql`query {
      hello
    }`,
    update: data => data.hello
  }
}

您也可以直接在 GraphQL 文档中重命名字段

js
apollo: {
  world: gql`query {
    world: hello
  }`
}

在此示例中,我们将hello字段重命名为world,以便vue-apollo可以自动推断出从结果中检索什么。

带参数的查询

您可以通过在对象中声明queryvariables而不是仅声明 GraphQL 查询,将变量(和其他参数)添加到gql查询中

js
// Apollo-specific options
apollo: {
  // Query with parameters
  ping: {
    // gql query
    query: gql`query PingMessage($message: String!) {
      ping(message: $message)
    }`,
    // Static parameters
    variables: {
      message: 'Meow',
    },
  },
},

您可以在对象中使用 apollowatchQuery选项,例如

  • fetchPolicy
  • pollInterval
  • ...

有关更多详细信息,请参阅apollo 文档

例如,您可以添加fetchPolicyapollo 选项,如下所示

js
apollo: {
  // Query with parameters
  ping: {
    query: gql`query PingMessage($message: String!) {
      ping(message: $message)
    }`,
    variables: {
      message: 'Meow'
    },
    // Additional options here
    fetchPolicy: 'cache-and-network',
  },
},

同样,您可以在 Vue 组件中初始化您的属性

js
data () {
  return {
    // Initialize your apollo data
    ping: '',
  }
},

在服务器端,添加相应的模式和解析器

js
export const schema = `
type Query {
  ping(message: String!): String
}

schema {
  query: Query
}
`

export const resolvers = {
  Query: {
    ping (root, { message }, context) {
      return `Answering ${message}`
    },
  },
}

然后在 Vue 组件中使用它

vue
<template>
  <div class="apollo">
    <h3>Ping</h3>
    <p>
      {{ ping }}
    </p>
  </div>
</template>

响应式参数

使用函数代替,以使参数与 Vue 属性保持响应性

js
// Apollo-specific options
apollo: {
  // Query with parameters
  ping: {
    query: gql`query PingMessage($message: String!) {
      ping(message: $message)
    }`,
    // Reactive parameters
    variables () {
      // Use vue reactive properties here
      return {
          message: this.pingInput,
      }
    },
  },
},

这将每次参数更改时重新获取查询,例如

vue
<template>
  <div class="apollo">
    <h3>Ping</h3>
    <input v-model="pingInput" placeholder="Enter a message" />
    <p>
      {{ping}}
    </p>
  </div>
</template>

加载状态

您可以使用$apollo.loading道具显示加载状态

vue
<div v-if="$apollo.loading">Loading...</div>

或者对于此特定的ping查询

vue
<div v-if="$apollo.queries.ping.loading">Loading...</div>

选项函数

您可以使用一个函数,该函数将在组件创建时被调用一次,并且必须返回选项对象

js
// Apollo-specific options
apollo: {
  // Query with parameters
  ping () {
    // This is called once when the component is created
    // It must return the option object
    return {
      // gql query
      query: gql`query PingMessage($message: String!) {
        ping(message: $message)
      }`,
      // Static parameters
      variables: {
        message: 'Meow',
      },
    }
  },
},

提示

这也适用于订阅

响应式查询定义

您可以为query选项使用函数。这将自动更新 graphql 查询定义

js
// The featured tag can be either a random tag or the last added tag
featuredTag: {
  query () {
    // Here you can access the component instance with 'this'
    if (this.showTag === 'random') {
      return gql`{
        randomTag {
          id
          label
          type
        }
      }`
    } else if (this.showTag === 'last') {
      return gql`{
        lastTag {
          id
          label
          type
        }
      }`
    }
  },
  // We need this to assign the value of the 'featuredTag' component property
  update: data => data.randomTag || data.lastTag,
},

提示

这也适用于订阅

跳过查询

如果跳过查询,它将禁用查询,并且结果将不再更新。您可以使用skip选项

js
// Apollo-specific options
apollo: {
  tags: {
    // GraphQL Query
    query: gql`query tagList ($type: String!) {
      tags(type: $type) {
        id
        label
      }
    }`,
    // Reactive variables
    variables () {
      return {
        type: this.type,
      }
    },
    // Disable the query
    skip () {
      return this.skipQuery
    },
  },
},

在这里,skip将在skipQuery组件属性更改时自动调用。

您也可以直接访问查询并设置skip属性

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

如果查询skip变为false,查询将自动再次执行。

响应式查询示例

这是一个使用轮询的响应式查询示例

js
// Apollo-specific options
apollo: {
  // 'tags' data property on vue instance
  tags: {
    query: gql`query tagList {
      tags {
        id,
        label
      }
    }`,
    pollInterval: 300, // ms
  },
},

以下是服务器端的样子

js
export const schema = `
type Tag {
  id: Int
  label: String
}

type Query {
  tags: [Tag]
}

schema {
  query: Query
}
`

// Fake word generator
import casual from 'casual'

// Let's generate some tags
var id = 0
var tags = []
for (let i = 0; i < 42; i++) {
  addTag(casual.word)
}

function addTag (label) {
  let t = {
    id: id++,
    label,
  }
  tags.push(t)
  return t
}

export const resolvers = {
  Query: {
    tags(root, args, context) {
      return tags
    },
  },
}

手动添加智能查询

您可以使用$apollo.addSmartQuery(key, options)方法手动添加智能查询

js
created () {
  this.$apollo.addSmartQuery('comments', {
    // Same options like above
  })
}

提示

在内部,此方法将针对组件apollo选项中的每个查询条目调用。

高级选项

还有更多特定于 vue-apollo 的选项,请参阅API 参考