docs: sync Chinese doc to 3.0.0-beta.30 (#604)
* docs: sync Chinese doc to 3.0.0-beta.29 * docs: sync Chinese doc to 3.0.0-beta.30 * main page
This commit is contained in:
@@ -207,8 +207,8 @@ module.exports = {
|
||||
collapsable: false,
|
||||
children: [
|
||||
'apollo-query',
|
||||
'apollo-subscribe-to-more',
|
||||
'apollo-mutation',
|
||||
'apollo-subscribe-to-more',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -52,7 +52,7 @@ To enable support of `gql` string tag in Vue templates, see the necessary setup
|
||||
|
||||
- `result`: Apollo Query result
|
||||
- `result.data`: Data returned by the query (can be transformed by the `update` prop)
|
||||
- `result.fullData`: Raw data returned by the query (not transformed by the `updated` prop)
|
||||
- `result.fullData`: Raw data returned by the query (not transformed by the `update` prop)
|
||||
- `result.loading`: Boolean indicating that a request is in flight (you may need to set `notifyOnNetworkStatusChange` prop for it to change)
|
||||
- `result.error`: Eventual error for the current result
|
||||
- `result.networkStatus`: See [apollo networkStatus](https://www.apollographql.com/docs/react/basics/queries.html#graphql-query-data-networkStatus)
|
||||
|
||||
@@ -38,7 +38,7 @@ export const typeDefs = gql`
|
||||
|
||||
`gql` here stands for the JavaScript template literal tag that parses GraphQL query strings.
|
||||
|
||||
Now we need to add `typeDefs` to our Apollo client
|
||||
Now we need to add `typeDefs` to our Apollo client.
|
||||
|
||||
```js{4-5}
|
||||
// main.js
|
||||
@@ -50,7 +50,7 @@ const apolloClient = new ApolloClient({
|
||||
```
|
||||
|
||||
:::warning WARNING
|
||||
As you can see, we've added also an empty `resolvers` object here: if we don't assign it to the Apollo client options, it won't recognize the queries to local state and will try to send a request to remote URL instead
|
||||
As you can see, we've added also an empty `resolvers` object here: if we don't assign it to the Apollo client options, it won't recognize the queries to local state and will try to send a request to remote URL instead.
|
||||
:::
|
||||
|
||||
## Extending a remote GraphQL schema locally
|
||||
@@ -264,7 +264,7 @@ const apolloClient = new ApolloClient({
|
||||
});
|
||||
```
|
||||
|
||||
After this, we can use the mutation in our Vue component like normal [mutations](apollo/mutations.md)
|
||||
After this, we can use the mutation in our Vue component like normal [mutations](apollo/mutations.md):
|
||||
|
||||
```js
|
||||
// App.vue
|
||||
|
||||
@@ -54,5 +54,5 @@ footer: LICENCE MIT - Created by Guillaume CHAU (@Akryum)
|
||||
</p>
|
||||
|
||||
::: tip 当前版本
|
||||
中文文档现在同步至 v3.0.0-beta.28
|
||||
中文文档现在同步至 v3.0.0-beta.30
|
||||
:::
|
||||
|
||||
@@ -1,8 +1,32 @@
|
||||
# ApolloMutation 组件
|
||||
|
||||
示例:
|
||||
|
||||
```vue
|
||||
<ApolloMutation
|
||||
:mutation="gql => gql`
|
||||
mutation DoStuff ($name: String!) {
|
||||
someWork (name: $name) {
|
||||
success
|
||||
timeSpent
|
||||
}
|
||||
}
|
||||
`"
|
||||
:variables="{
|
||||
name
|
||||
}"
|
||||
@done="onDone"
|
||||
>
|
||||
<template v-slot="{ mutate, loading, error }">
|
||||
<button :disabled="loading" @click="mutate()">Click me</button>
|
||||
<p v-if="error">An error occured: {{ error }}</p>
|
||||
</template>
|
||||
</ApolloMutation>
|
||||
```
|
||||
|
||||
## Props
|
||||
|
||||
- `mutation`:GraphQL 查询(由 `graphql-tag` 转换)
|
||||
- `mutation`:GraphQL 查询(由 `graphql-tag` 转换)或一个接收 `gql` 标签作为参数并返回转换后的查询的函数
|
||||
- `variables`:GraphQL 变量对象
|
||||
- `optimisticResponse`:详见 [乐观 UI](https://www.apollographql.com/docs/react/features/optimistic-ui.html)
|
||||
- `update`:详见 [变更后更新缓存](https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-mutation-options-update)
|
||||
@@ -21,3 +45,4 @@
|
||||
|
||||
- `done(resultObject)`
|
||||
- `error(errorObject)`
|
||||
- `loading(boolean)`
|
||||
|
||||
@@ -1,28 +1,62 @@
|
||||
# ApolloQuery 组件
|
||||
|
||||
示例:
|
||||
|
||||
```vue
|
||||
<ApolloQuery
|
||||
:query="gql => gql`
|
||||
query MyHelloQuery ($name: String!) {
|
||||
hello (name: $name)
|
||||
}
|
||||
`"
|
||||
:variables="{ name }"
|
||||
>
|
||||
<template v-slot="{ result: { error, data }, isLoading }">
|
||||
<!-- Loading -->
|
||||
<div v-if="isLoading" class="loading apollo">Loading...</div>
|
||||
|
||||
<!-- Error -->
|
||||
<div v-else-if="error" class="error apollo">An error occured</div>
|
||||
|
||||
<!-- Result -->
|
||||
<div v-else-if="data" class="result apollo">{{ data.hello }}</div>
|
||||
|
||||
<!-- No result -->
|
||||
<div v-else class="no-result apollo">No result :(</div>
|
||||
</template>
|
||||
</ApolloQuery>
|
||||
```
|
||||
|
||||
::: warning
|
||||
要在 Vue 模板中启用对 `gql` 字符串标签的支持,请在 [指南](../guide/components/query.md#tag-setup) 中查看必要的设置。
|
||||
:::
|
||||
|
||||
## Props
|
||||
|
||||
- `query`:GraphQL 查询(由 `graphql-tag` 转换)
|
||||
- `query`:GraphQL 查询(由 `graphql-tag` 转换)或一个接收 `gql` 标签作为参数并返回转换后的查询的函数
|
||||
- `variables`:GraphQL 变量对象
|
||||
- `fetchPolicy`:详见 [apollo fetchPolicy](https://www.apollographql.com/docs/react/basics/queries.html#graphql-config-options-fetchPolicy)
|
||||
- `pollInterval`:详见 [apollo pollInterval](https://www.apollographql.com/docs/react/basics/queries.html#graphql-config-options-pollInterval)
|
||||
- `notifyOnNetworkStatusChange`:详见 [apollo notifyOnNetworkStatusChange](https://www.apollographql.com/docs/react/basics/queries.html#graphql-config-options-notifyOnNetworkStatusChange)
|
||||
- `context`:详见 [apollo context](https://www.apollographql.com/docs/react/basics/queries.html#graphql-config-options-context)
|
||||
- `update`:用于转换结果 `data` 的函数,用于在响应中选择特定部分。示例:`:update="data => data.user.messages"`
|
||||
- `skip`:布尔值,禁用查询获取
|
||||
- `clientId`:查询所使用的 Apollo 客户端 id(在 ApolloProvider 的 `clients` 选项中定义)
|
||||
- `deep`:布尔值,使用深度 Vue 侦听器
|
||||
- `tag`:字符串,HTML 标签名(默认值:`div`);如果是假值(如 `null` 或 `undefined`),该组件将成为无渲染组件(内容不会被包装在标签中),在这种情况下,只有第一个子元素会被渲染
|
||||
- `debounce`:对重新获取查询结果的防抖毫秒数(例如当变量更改时)
|
||||
- `throttle`:对重新获取查询结果的节流毫秒数(例如当变量更改时)
|
||||
- `prefetch`:如为 `false`,将跳过 SSR 期间的预取
|
||||
|
||||
## 作用域插槽
|
||||
|
||||
- `result`:Apollo 查询结果
|
||||
- `result.data`:查询返回的数据
|
||||
- `result.loading`:布尔值,表明请求正在进行中
|
||||
- `result.data`:查询返回的数据(可使用 `update` 属性转换)
|
||||
- `result.fullData`:查询返回的原始数据(未使用 `update` 属性转换)
|
||||
- `result.loading`:布尔值,表明请求正在进行中(你可能需要设置 `notifyOnNetworkStatusChange` 属性来修改它)
|
||||
- `result.error`:当前结果的最终错误
|
||||
- `result.networkStatus`:详见 [apollo networkStatus](https://www.apollographql.com/docs/react/basics/queries.html#graphql-query-data-networkStatus)
|
||||
- `query`:与组件关联的智能查询
|
||||
- `query`:与组件关联的智能查询,用于执行 `query.refetch()` 或 `query.fetchMore()` 之类的操作
|
||||
- `isLoading`:智能查询加载状态
|
||||
- `gqlError`:第一个 GraphQL 错误(如果有)
|
||||
- `times`:结果被更新的次数
|
||||
@@ -31,3 +65,4 @@
|
||||
|
||||
- `result(resultObject)`
|
||||
- `error(errorObject)`
|
||||
- `loading(boolean)`
|
||||
|
||||
@@ -1,7 +1,55 @@
|
||||
# ApolloSubscribeToMore 组件
|
||||
|
||||
示例:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<ApolloQuery :query="...">
|
||||
<ApolloSubscribeToMore
|
||||
:document="gql => gql`
|
||||
subscription messageChanged ($channelId: ID!) {
|
||||
messageAdded (channelId: $channelId) {
|
||||
type
|
||||
message {
|
||||
id
|
||||
text
|
||||
}
|
||||
}
|
||||
}
|
||||
`"
|
||||
:variables="{ channelId }"
|
||||
:updateQuery="onMessageAdded"
|
||||
/>
|
||||
|
||||
<!-- ... -->
|
||||
</ApolloQuery>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
channel: 'general',
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onMessageAdded (previousResult, { subscriptionData }) {
|
||||
// 以前的结果是不可变的
|
||||
const newResult = {
|
||||
messages: [...previousResult.messages],
|
||||
}
|
||||
// 添加新内容到列表
|
||||
newResult.messages.push(subscriptionData.data.messageAdded)
|
||||
return newResult
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
## Props
|
||||
|
||||
- `document`:包含订阅的 GraphQL 文档。
|
||||
- `document`:包含订阅的 GraphQL 文档,或一个接收 `gql` 标签作为参数并返回转换后的文档的函数。
|
||||
- `variables`:将自动更新订阅变量的对象。
|
||||
- `updateQuery`:可以根据需要更新查询结果的函数。
|
||||
|
||||
@@ -27,7 +27,7 @@ this.$apollo.subscriptions.users.skip = true
|
||||
停止并重新启动查询:
|
||||
|
||||
```js
|
||||
this.$apollo.subscriptions.users.restart()
|
||||
this.$apollo.subscriptions.users.refresh()
|
||||
```
|
||||
|
||||
### start
|
||||
|
||||
@@ -40,9 +40,9 @@ const wsLink = new WebSocketLink({
|
||||
const link = split(
|
||||
// 根据操作类型分割
|
||||
({ query }) => {
|
||||
const { kind, operation } = getMainDefinition(query)
|
||||
return kind === 'OperationDefinition' &&
|
||||
operation === 'subscription'
|
||||
const definition = getMainDefinition(query)
|
||||
return definition.kind === 'OperationDefinition' &&
|
||||
definition.operation === 'subscription'
|
||||
},
|
||||
wsLink,
|
||||
httpLink
|
||||
@@ -61,7 +61,7 @@ Vue.use(VueApollo)
|
||||
|
||||
## 订阅更多
|
||||
|
||||
如果你需要更新一个来自订阅的查询结果,最好的方式是使用 `subscribeToMore` 查询方法。它将创建链接到查询的 [智能订阅](../../api/smart-subscription.md)。你只需要将 `subscribeToMore` 添加到查询中:
|
||||
如果你需要更新一个来自订阅的智能查询结果,最好的方式是使用 `subscribeToMore` 查询方法。它将创建链接到智能查询的 [智能订阅](../../api/smart-subscription.md)。你只需要将 `subscribeToMore` 添加到智能查询中:
|
||||
|
||||
```js
|
||||
apollo: {
|
||||
@@ -201,8 +201,9 @@ apollo: {
|
||||
}
|
||||
},
|
||||
// 结果钩子
|
||||
result (data) {
|
||||
console.log(data)
|
||||
// 不要忘记对 `data` 进行解构
|
||||
result ({ data }) {
|
||||
console.log(data.tagAdded)
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -4,34 +4,26 @@
|
||||
|
||||
这样做的好处是你可以直接在模板中使用这些组件,而不是使用组件的 `apollo` 选项。在某些情况下,你甚至不需要在 `.vue` 中添加脚本部分!这种代码会更加声明式。
|
||||
|
||||
这是一个模板中 `ApolloQuery` 的简单示例:
|
||||
这是一个模板中 [ApolloQuery](./query.md) 的简单示例:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="users-list">
|
||||
<!-- Apollo 查询 -->
|
||||
<ApolloQuery :query="require('@/graphql/users.gql')">
|
||||
<!-- 结果将自动更新 -->
|
||||
<template slot-scope="{ result: { data, loading } }">
|
||||
<!-- 一些内容 -->
|
||||
<div v-if="loading">Loading...</div>
|
||||
<ul v-else>
|
||||
<li v-for="user of data.users" class="user">
|
||||
{{ user.name }}
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</ApolloQuery>
|
||||
</div>
|
||||
<!-- Apollo 查询 -->
|
||||
<ApolloQuery :query="/* 一些查询 */">
|
||||
<!-- 结果将自动更新 -->
|
||||
<template slot-scope="{ result: { data, loading } }">
|
||||
<!-- 一些内容 -->
|
||||
<div v-if="loading">Loading...</div>
|
||||
<ul v-else>
|
||||
<li v-for="user of data.users" class="user">
|
||||
{{ user.name }}
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</ApolloQuery>
|
||||
</template>
|
||||
|
||||
<!-- 不需要脚本 -->
|
||||
|
||||
<style scoped>
|
||||
.user {
|
||||
list-style: none;
|
||||
padding: 12px;
|
||||
color: blue;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
在 [ApolloQuery](./query.md) 查看如何在模板中编写 GraphQL 查询。
|
||||
|
||||
@@ -6,18 +6,205 @@
|
||||
|
||||
```vue
|
||||
<ApolloMutation
|
||||
:mutation="require('@/graphql/userLogin.gql')"
|
||||
:mutation="gql => gql`
|
||||
mutation DoStuff ($name: String!) {
|
||||
someWork (name: $name) {
|
||||
success
|
||||
timeSpent
|
||||
}
|
||||
}
|
||||
`"
|
||||
:variables="{
|
||||
email,
|
||||
password,
|
||||
name
|
||||
}"
|
||||
@done="onDone"
|
||||
>
|
||||
<template slot-scope="{ mutate, loading, error }">
|
||||
<template v-slot="{ mutate, loading, error }">
|
||||
<button :disabled="loading" @click="mutate()">Click me</button>
|
||||
<p v-if="error">An error occured: {{ error }}</p>
|
||||
</template>
|
||||
</ApolloMutation>
|
||||
```
|
||||
|
||||
更多参见 [API 参考](../../api/apollo-mutation.md).
|
||||
在 [ApolloQuery](./query.md) 查看如何在模板中编写 GraphQL 查询。
|
||||
|
||||
在 [API 参考](../../api/apollo-mutation.md) 查看所有可用的选项。
|
||||
|
||||
## 更新缓存
|
||||
|
||||
如果变更只更新缓存中已有的对象(例如编辑现有字段),则你不需要进行任何操作,因为 Apollo Client 将自动更新缓存,但仅当变更结果中的对象包含 `__typename` 和 `id` 字段(或用于 [规范化缓存](https://www.apollographql.com/docs/react/advanced/caching#normalization) 的自定义字段)时适用。
|
||||
|
||||
否则,你需要告知 Apollo Client 如何使用变更结果来更新缓存。例如,如果变更添加了新项目,则必须更新相关查询结果以有效地将此新项目推送到查询中。
|
||||
|
||||
### 添加项目
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<ApolloMutation
|
||||
:mutation="gql => gql`
|
||||
mutation ($input: SendMessageToThreadInput!) {
|
||||
sendMessageToThread (input: $input) {
|
||||
message {
|
||||
...message
|
||||
}
|
||||
}
|
||||
}
|
||||
${$options.fragments.message}
|
||||
`"
|
||||
:variables="{
|
||||
threadId,
|
||||
text
|
||||
}"
|
||||
:update="updateCache"
|
||||
>
|
||||
<!-- 这里是表单 -->
|
||||
</ApolloMutation>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import gql from 'gql-tag'
|
||||
|
||||
const fragments = {
|
||||
message: gql`
|
||||
fragment message on Message {
|
||||
id
|
||||
text
|
||||
user {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
export default {
|
||||
fragments,
|
||||
|
||||
props: {
|
||||
threadId: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateCache (store, { data: { sendMessageToThread } }) {
|
||||
const query = {
|
||||
query: gql`
|
||||
query ($threadId: ID!) {
|
||||
thread (id: $threadId) {
|
||||
id
|
||||
messages {
|
||||
...message
|
||||
}
|
||||
}
|
||||
}
|
||||
${fragments.message}
|
||||
`,
|
||||
variables: {
|
||||
threadId: this.threadId,
|
||||
},
|
||||
}
|
||||
// 读取缓存中的查询
|
||||
const data = store.readQuery(query)
|
||||
// 变更缓存结果
|
||||
data.thread.messages.push(sendMessageToThread.message)
|
||||
// 将结果写回缓存
|
||||
store.writeQuery({
|
||||
...query,
|
||||
data,
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### 移除项目
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<ApolloMutation
|
||||
:mutation="gql => gql`
|
||||
mutation ($input: DeleteMessageFromThreadInput!) {
|
||||
deleteMessageFromThread (input: $input) {
|
||||
success
|
||||
}
|
||||
}
|
||||
`"
|
||||
:variables="{
|
||||
threadId,
|
||||
messageId
|
||||
}"
|
||||
:update="updateCache"
|
||||
>
|
||||
<!-- 这里是表单 -->
|
||||
</ApolloMutation>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import gql from 'gql-tag'
|
||||
|
||||
const fragments = {
|
||||
message: gql`
|
||||
fragment message on Message {
|
||||
id
|
||||
text
|
||||
user {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
export default {
|
||||
fragments,
|
||||
|
||||
props: {
|
||||
threadId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
messageId: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateCache (store, { data: { deleteMessageFromThread } }) {
|
||||
const query = {
|
||||
query: gql`
|
||||
query ($threadId: ID!) {
|
||||
thread (id: $threadId) {
|
||||
id
|
||||
messages {
|
||||
...message
|
||||
}
|
||||
}
|
||||
}
|
||||
${fragments.message}
|
||||
`,
|
||||
variables: {
|
||||
threadId: this.threadId,
|
||||
},
|
||||
}
|
||||
// 读取缓存中的查询
|
||||
const data = store.readQuery(query)
|
||||
// 查找需要删除的项目
|
||||
const index = data.thread.messages.findIndex(m => m.id === this.messageId)
|
||||
if (index !== -1) {
|
||||
// 变更缓存结果
|
||||
data.thread.messages.splice(index, 1)
|
||||
// 将结果写回缓存
|
||||
store.writeQuery({
|
||||
...query,
|
||||
data,
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -2,27 +2,427 @@
|
||||
|
||||
你可以使用 `ApolloQuery`(或 `apollo-query`)组件直接在模板中侦听 Apollo 查询。
|
||||
|
||||
这是一个简单的例子:
|
||||
阅读完本页后,在 [API 参考](../../api/apollo-query.md) 查看所有可用的选项。
|
||||
|
||||
## 使用 gql 标签的查询
|
||||
|
||||
这是使用 `ApolloQuery` 组件的推荐方法。它与 `gql` 标签使用相同的语法,就像在其他示例中一样:
|
||||
|
||||
```vue
|
||||
<ApolloQuery
|
||||
:query="require('../graphql/HelloWorld.gql')"
|
||||
:variables="{ name }"
|
||||
>
|
||||
<template slot-scope="{ result: { loading, error, data } }">
|
||||
<!-- Loading -->
|
||||
<div v-if="loading" class="loading apollo">Loading...</div>
|
||||
|
||||
<!-- Error -->
|
||||
<div v-else-if="error" class="error apollo">An error occured</div>
|
||||
|
||||
<!-- Result -->
|
||||
<div v-else-if="data" class="result apollo">{{ data.hello }}</div>
|
||||
|
||||
<!-- No result -->
|
||||
<div v-else class="no-result apollo">No result :(</div>
|
||||
</template>
|
||||
</ApolloQuery>
|
||||
<template>
|
||||
<ApolloQuery
|
||||
:query="gql => gql`
|
||||
query MyHelloQuery ($name: String!) {
|
||||
hello (name: $name)
|
||||
}
|
||||
`"
|
||||
:variables="{ name }"
|
||||
>
|
||||
<!-- TODO -->
|
||||
</ApolloQuery>
|
||||
</template>
|
||||
```
|
||||
|
||||
更多参见 [API 参考](../../api/apollo-query.md).
|
||||
我们将一个函数传递给 `query` 属性,它将 `gql` 标签作为参数,因此我们可以直接编写 GraphQL 文档。
|
||||
|
||||
上面的例子中还包含将 `variables` 通过其同名属性传递给查询的功能。
|
||||
|
||||
在 `ApolloQuery` 的默认插槽中,你可以访问有关被侦听查询的各种插槽数据,比如 `result` 对象:
|
||||
|
||||
```vue
|
||||
<template v-slot="{ result: { loading, error, data } }">
|
||||
<!-- Loading -->
|
||||
<div v-if="loading" class="loading apollo">Loading...</div>
|
||||
|
||||
<!-- Error -->
|
||||
<div v-else-if="error" class="error apollo">An error occured</div>
|
||||
|
||||
<!-- Result -->
|
||||
<div v-else-if="data" class="result apollo">{{ data.hello }}</div>
|
||||
|
||||
<!-- No result -->
|
||||
<div v-else class="no-result apollo">No result :(</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
这是一个完整的示例组件:
|
||||
|
||||
```vue
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
name: 'Anne'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<input v-model="name" placeholder="Enter your name">
|
||||
|
||||
<ApolloQuery
|
||||
:query="gql => gql`
|
||||
query MyHelloQuery ($name: String!) {
|
||||
hello (name: $name)
|
||||
}
|
||||
`"
|
||||
:variables="{ name }"
|
||||
>
|
||||
<template v-slot="{ result: { loading, error, data } }">
|
||||
<!-- Loading -->
|
||||
<div v-if="loading" class="loading apollo">Loading...</div>
|
||||
|
||||
<!-- Error -->
|
||||
<div v-else-if="error" class="error apollo">An error occured</div>
|
||||
|
||||
<!-- Result -->
|
||||
<div v-else-if="data" class="result apollo">{{ data.hello }}</div>
|
||||
|
||||
<!-- No result -->
|
||||
<div v-else class="no-result apollo">No result :(</div>
|
||||
</template>
|
||||
</ApolloQuery>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 配置标签
|
||||
|
||||
如果你没有使用 [vue-cli-plugin-apollo](https://github.com/Akryum/vue-cli-plugin-apollo) (`v0.20.0+`),则需要配置 [vue-loader](https://vue-loader.vuejs.org) 来转换字符串模板标签。`vue-loader` 在底层使用 [Bublé](https://buble.surge.sh/guide/) 来转换组件模板中的代码。我们需要将 `dangerousTaggedTemplateString` 变换添加到 Bublé 以使 `gql` 起作用。例如,在使用 Vue CLI 时:
|
||||
|
||||
```js
|
||||
// vue.config.js
|
||||
|
||||
module.exports = {
|
||||
chainWebpack: config => {
|
||||
config.module
|
||||
.rule('vue')
|
||||
.use('vue-loader')
|
||||
.loader('vue-loader')
|
||||
.tap(options => {
|
||||
options.transpileOptions = {
|
||||
transforms: {
|
||||
dangerousTaggedTemplateString: true,
|
||||
},
|
||||
}
|
||||
return options
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
在原始的 Webpack 配置中,它将如下所示:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'vue-loader',
|
||||
options: {
|
||||
transpileOptions: {
|
||||
transforms: {
|
||||
dangerousTaggedTemplateString: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
/* 其他规则 ... */
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 使用 gql 文件的查询
|
||||
|
||||
使用本组件的另一种方法是创建单独的 `.gql` 文件。这些文件需要使用 [graphql-tag](https://github.com/apollographql/graphql-tag#webpack-preprocessing-with-graphql-tagloader) 进行预处理。
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<ApolloQuery
|
||||
:query="require('../graphql/HelloWorld.gql')"
|
||||
:variables="{ name }"
|
||||
>
|
||||
<template v-slot="{ result: { loading, error, data } }">
|
||||
<!-- Loading -->
|
||||
<div v-if="loading" class="loading apollo">Loading...</div>
|
||||
|
||||
<!-- Error -->
|
||||
<div v-else-if="error" class="error apollo">An error occured</div>
|
||||
|
||||
<!-- Result -->
|
||||
<div v-else-if="data" class="result apollo">{{ data.hello }}</div>
|
||||
|
||||
<!-- No result -->
|
||||
<div v-else class="no-result apollo">No result :(</div>
|
||||
</template>
|
||||
</ApolloQuery>
|
||||
</template>
|
||||
```
|
||||
|
||||
## 查询操作
|
||||
|
||||
你可以使用 `query` 插槽属性来访问智能查询对象。下面是使用 `fetchMore` 分页数据的示例组件:
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<ApolloQuery
|
||||
:query="/* query */"
|
||||
:variables="{
|
||||
limit: $options.pageSize
|
||||
}"
|
||||
v-slot="{ result: { loading, error, data }, query }"
|
||||
>
|
||||
<!-- 在这里显示数据 -->
|
||||
<button v-if="hasMore" @click="loadMore(query)">Load more</button>
|
||||
</ApolloQuery>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
pageSize: 10,
|
||||
|
||||
data: {
|
||||
return {
|
||||
page: 1,
|
||||
hasMore: true
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
async loadMore (query) {
|
||||
await query.fetchMore({
|
||||
variables: {
|
||||
offset: this.page++ * this.$options.pageSize
|
||||
},
|
||||
updateQuery: (prev, { fetchMoreResult }) => {
|
||||
if (!fetchMoreResult || fetchMoreResult.product.length === 0) {
|
||||
this.hasMore = false
|
||||
return prev
|
||||
}
|
||||
return Object.assign({}, prev, {
|
||||
product: [...prev.product, ...fetchMoreResult.product]
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
在 [API 参考](../../api/smart-query.md#methods) 查看所有可用的智能查询方法。
|
||||
|
||||
## 使用片段
|
||||
|
||||
片段可用于在其他文档中共享部分 GraphQL 文档,以便一致地检索相同的数据,且无需复制粘贴代码。
|
||||
|
||||
假设我们有一个`GetMessages` 查询,带有一个类型是 `Message` 对象数组的 `messages` 字段:
|
||||
|
||||
```gql
|
||||
query GetMessages {
|
||||
messages {
|
||||
id
|
||||
user {
|
||||
id
|
||||
name
|
||||
}
|
||||
text
|
||||
created
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
我们想要将 `messages` 中 `Message` 类型的所有字段提取到一个片段中,以使我们可以在其他地方重复使用它。
|
||||
|
||||
首先将 `gql` 标签导入组件:
|
||||
|
||||
```js
|
||||
import gql from 'graphql-tag'
|
||||
```
|
||||
|
||||
然后,在组件定义中,声明一个新的 `fragments` 对象:
|
||||
|
||||
```js
|
||||
export default {
|
||||
fragments: {
|
||||
/** TODO */
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
以下是应用于 `Message` 类型的 `message` 片段,如下所示:
|
||||
|
||||
```gql
|
||||
fragment message on Message {
|
||||
id
|
||||
user {
|
||||
id
|
||||
name
|
||||
}
|
||||
text
|
||||
created
|
||||
}
|
||||
```
|
||||
|
||||
我们可以像查询一样使用 `gql` 标签:
|
||||
|
||||
```js
|
||||
export default {
|
||||
fragments: {
|
||||
message: gql`
|
||||
fragment message on Message {
|
||||
id
|
||||
user {
|
||||
id
|
||||
name
|
||||
}
|
||||
text
|
||||
created
|
||||
}
|
||||
`
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
我们现在可以在组件中使用 `this.$options.fragments.message` 访问该片段。要在我们的 `GetMessages` 查询中使用此片段,我们需要使用 GraphQL 的 `...` 展开运算符,并将片段放在查询旁边:
|
||||
|
||||
```js
|
||||
gql`
|
||||
query GetMessages {
|
||||
messages {
|
||||
...message
|
||||
}
|
||||
}
|
||||
${$options.fragments.message}
|
||||
`
|
||||
```
|
||||
|
||||
这将有效地生成 GraphQL 文档(你可以在你的 GraphQL API playground 上尝试):
|
||||
|
||||
```gql
|
||||
query GetMessages {
|
||||
messages {
|
||||
...message
|
||||
}
|
||||
}
|
||||
fragment message on Message {
|
||||
id
|
||||
user {
|
||||
id
|
||||
name
|
||||
}
|
||||
text
|
||||
created
|
||||
}
|
||||
```
|
||||
|
||||
那么这里发生了什么?GraphQL 将找到 `...` 运算符,表明我们将在查询的 `messages` 字段中选择字段。`...` 运算符之后是片段名称 `message`,然后在整个 GraphQL 文档中查找片段。由于我们已经正确定义了片段,因此它能够在查询下面被找到。最后,GraphQL 将复制所有片段内容并用它替换 `...message`。
|
||||
|
||||
最后,我们获得最终查询:
|
||||
|
||||
```gql
|
||||
query GetMessages {
|
||||
messages {
|
||||
id
|
||||
user {
|
||||
id
|
||||
name
|
||||
}
|
||||
text
|
||||
created
|
||||
}
|
||||
}
|
||||
fragment message on Message {
|
||||
id
|
||||
user {
|
||||
id
|
||||
name
|
||||
}
|
||||
text
|
||||
created
|
||||
}
|
||||
```
|
||||
|
||||
这是一个完整的示例组件:
|
||||
|
||||
```vue
|
||||
<!-- MessageList.vue -->
|
||||
<script>
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export default {
|
||||
fragments: {
|
||||
message: gql`
|
||||
fragment message on Message {
|
||||
id
|
||||
user {
|
||||
id
|
||||
name
|
||||
}
|
||||
text
|
||||
created
|
||||
}
|
||||
`
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ApolloQuery
|
||||
:query="gql => gql`
|
||||
query GetMessages {
|
||||
messages {
|
||||
...message
|
||||
}
|
||||
}
|
||||
${$options.fragments.message}
|
||||
`"
|
||||
>
|
||||
<!-- 内容... -->
|
||||
</ApolloQuery>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 重复使用片段
|
||||
|
||||
现在我们可以在另一个组件中检索 `message` 片段:
|
||||
|
||||
```vue
|
||||
<!-- MessageForm.vue -->
|
||||
<script>
|
||||
import gql from 'graphql-tag'
|
||||
import MessageList from './MessageList.vue'
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
async sendMessage () {
|
||||
await this.$apollo.mutate({
|
||||
mutation: gql`
|
||||
mutation SendMessage ($input: SendMessageInput!) {
|
||||
addMessage (input: $input) {
|
||||
newMessage {
|
||||
...message
|
||||
}
|
||||
}
|
||||
}
|
||||
${MessageList.fragments.message}
|
||||
`,
|
||||
variables: {
|
||||
/* 这里是变量 */
|
||||
},
|
||||
/* 这里是其他选项 */
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -12,8 +12,18 @@
|
||||
<template>
|
||||
<ApolloQuery :query="...">
|
||||
<ApolloSubscribeToMore
|
||||
:document="require('../gql/MessageAdded.gql')"
|
||||
:variables="{ channel }"
|
||||
:document="gql => gql`
|
||||
subscription messageChanged ($channelId: ID!) {
|
||||
messageAdded (channelId: $channelId) {
|
||||
type
|
||||
message {
|
||||
id
|
||||
text
|
||||
}
|
||||
}
|
||||
}
|
||||
`"
|
||||
:variables="{ channelId }"
|
||||
:updateQuery="onMessageAdded"
|
||||
/>
|
||||
|
||||
@@ -44,7 +54,9 @@ export default {
|
||||
</script>
|
||||
```
|
||||
|
||||
更多参见 [API 参考](../../api/apollo-subscribe-to-more.md).
|
||||
在 [ApolloQuery](./query.md) 查看如何在模板中编写 GraphQL 查询。
|
||||
|
||||
在 [API 参考](../../api/apollo-subscribe-to-more.md) 查看所有可用的选项。
|
||||
|
||||
## `updateQuery` 的示例
|
||||
|
||||
|
||||
@@ -65,11 +65,11 @@ yarn add vue-apollo graphql apollo-client apollo-link apollo-link-http apollo-ca
|
||||
|
||||
```js
|
||||
import { ApolloClient } from 'apollo-client'
|
||||
import { HttpLink } from 'apollo-link-http'
|
||||
import { createHttpLink } from 'apollo-link-http'
|
||||
import { InMemoryCache } from 'apollo-cache-inmemory'
|
||||
|
||||
// 与 API 的 HTTP 连接
|
||||
const httpLink = new HttpLink({
|
||||
const httpLink = createHttpLink({
|
||||
// 你需要在这里使用绝对路径
|
||||
uri: 'http://localhost:3020/graphql',
|
||||
})
|
||||
@@ -115,3 +115,29 @@ new Vue({
|
||||
```
|
||||
|
||||
现在你已经完成了在组件中使用 Apollo 的所有准备了!
|
||||
|
||||
## IDE 集成
|
||||
|
||||
### Visual Studio Code
|
||||
|
||||
如果你使用 VS Code,建议安装 [Apollo GraphQL 扩展](https://marketplace.visualstudio.com/items?itemName=apollographql.vscode-apollo)。
|
||||
|
||||
然后在 Vue 项目的根文件夹中创建 `apollo.config.js` 文件来配置它:
|
||||
|
||||
```js
|
||||
// apollo.config.js
|
||||
module.exports = {
|
||||
client: {
|
||||
service: {
|
||||
name: 'my-app',
|
||||
// GraphQL API 的 URL
|
||||
url: 'http://localhost:3000/graphql',
|
||||
},
|
||||
// 通过扩展名选择需要处理的文件
|
||||
includes: [
|
||||
'src/**/*.vue',
|
||||
'src/**/*.js',
|
||||
],
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
+270
-31
@@ -1,41 +1,280 @@
|
||||
# 本地状态
|
||||
|
||||
如果你需要管理本地数据,你可以使用 [apollo-link-state](https://github.com/apollographql/apollo-link-state) 和 `@client` 指令来实现:
|
||||
## 为什么要使用 Apollo 的本地状态管理?
|
||||
|
||||
当你使用 Apollo 执行 GraphQL 查询时,API 调用的结果将存储在 **Apollo 缓存**中。现在想象一下,你还需要存储一些本地应用状态并使之可用于不同的组件。通常,在 Vue 应用中我们可以使用 [Vuex](https://vuex.vuejs.org/) 来实现这一需求。但同时使用 Apollo 和 Vuex 意味着你将数据存储到了两个不同的位置,导致你拥有**两个数据源**。
|
||||
|
||||
好在 Apollo 具有将本地应用数据存储到缓存的机制。以前,它使用了 [apollo-link-state](https://github.com/apollographql/apollo-link-state) 库来实现。在 Apollo 2.5 发布后这个功能被包含在 Apollo 核心中。
|
||||
|
||||
## 创建一个本地 schema
|
||||
|
||||
如同创建 GraphQL schema 是在服务端定义数据模型的第一步一样,编写本地 schema 是我们在客户端进行的第一步。
|
||||
|
||||
让我们创建一个本地 schema 来描述将在 todo 列表中作为单个事项的元素。在这个事项中应该有一些文本、一些定义它是否已经完成的属性、以及一个 ID 来区分不同的待办事项。所以,它应该是一个具有三个属性的对象:
|
||||
|
||||
```js
|
||||
export default {
|
||||
apollo: {
|
||||
hello: gql`
|
||||
query {
|
||||
hello @client {
|
||||
msg
|
||||
}
|
||||
}
|
||||
`
|
||||
},
|
||||
mounted () {
|
||||
// 变更 hello 消息
|
||||
this.$apollo
|
||||
.mutate({
|
||||
mutation: gql`
|
||||
mutation($msg: String!) {
|
||||
updateHello(message: $msg) @client
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
msg: 'hello from link-state!'
|
||||
}
|
||||
})
|
||||
}
|
||||
{
|
||||
id: 'uniqueId',
|
||||
text: 'some text',
|
||||
done: false
|
||||
}
|
||||
```
|
||||
|
||||
用这种方法来管理客户端状态正变得流行起来。有些项目甚至将其用作 Vuex(或其他灵感来源于 Flux 的解决方案)的替代品。
|
||||
现在我们可以将 `Item` 类型添加到本地 GraphQL schema 中。
|
||||
|
||||
## 示例
|
||||
```js
|
||||
//main.js
|
||||
|
||||
- [示例项目](https://codesandbox.io/s/zqqj82396p) (by @chriswingler)
|
||||
- [Todo App](https://codesandbox.io/s/x2jr96r8pp) (by @NikkitaFTW)
|
||||
- [Todo App - 扩展](https://codesandbox.io/s/k3621oko23) (by @ScottMolinari fork of @NikkitaFTW's)
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
---
|
||||
export const typeDefs = gql`
|
||||
type Item {
|
||||
id: ID!
|
||||
text: String!
|
||||
done: Boolean!
|
||||
}
|
||||
`;
|
||||
```
|
||||
|
||||
这里的 `gql` 代表解析 GraphQL 查询字符串的 JavaScript 模板字符串标签。
|
||||
|
||||
现在我们需要将 `typeDefs` 添加到我们的 Apollo 客户端。
|
||||
|
||||
```js{4-5}
|
||||
// main.js
|
||||
|
||||
const apolloClient = new ApolloClient({
|
||||
typeDefs,
|
||||
resolvers: {},
|
||||
});
|
||||
```
|
||||
|
||||
:::warning WARNING
|
||||
正如你所见,我们在此处添加了一个空的 `resolvers` 对象:如果我们不将它添加到 Apollo 客户端的选项,它将无法识别对本地状态的查询,并将尝试向远程 URL 发送请求。
|
||||
:::
|
||||
|
||||
## 在本地扩展一个远程 GraphQL schema
|
||||
|
||||
除了从零开始创建本地 schema 之外,你还可以将本地的**虚拟字段**添加到现有的远程 schema 中。这些字段仅存在于客户端上,可用于使用本地状态装饰服务端数据。
|
||||
|
||||
想象我们的远程 schema 中有一个 `User` 类型:
|
||||
|
||||
```js
|
||||
type User {
|
||||
name: String!
|
||||
age: Int!
|
||||
}
|
||||
```
|
||||
|
||||
而我们想要给 `User` 添加一个只在本地拥有的属性:
|
||||
|
||||
```js
|
||||
export const schema = gql`
|
||||
extend type User {
|
||||
twitter: String
|
||||
}
|
||||
`;
|
||||
```
|
||||
|
||||
现在,在查询用户时,我们需要指定 `twitter` 是本地字段:
|
||||
|
||||
```js
|
||||
const userQuery = gql`
|
||||
user {
|
||||
name
|
||||
age
|
||||
twitter @client
|
||||
}
|
||||
`;
|
||||
```
|
||||
|
||||
## 初始化 Apollo 缓存
|
||||
|
||||
要在应用中初始化 Apollo 缓存,需要使用 `InMemoryCache` 构造函数。首先,将它导入你的主文件:
|
||||
|
||||
```js{4,6}
|
||||
// main.js
|
||||
|
||||
import ApolloClient from 'apollo-boost';
|
||||
import { InMemoryCache } from 'apollo-cache-inmemory';
|
||||
|
||||
const cache = new InMemoryCache();
|
||||
```
|
||||
|
||||
现在我们需要在 Apollo 客户端选项中添加缓存:
|
||||
|
||||
```js{4}
|
||||
//main.js
|
||||
|
||||
const apolloClient = new ApolloClient({
|
||||
cache,
|
||||
typeDefs,
|
||||
resolvers: {},
|
||||
});
|
||||
```
|
||||
|
||||
现在缓存是空的。要向缓存添加一些初始数据,我们需要使用 `writeData` 方法:
|
||||
|
||||
```js{9-20}
|
||||
// main.js
|
||||
|
||||
const apolloClient = new ApolloClient({
|
||||
cache,
|
||||
typeDefs,
|
||||
resolvers: {},
|
||||
});
|
||||
|
||||
cache.writeData({
|
||||
data: {
|
||||
todoItems: [
|
||||
{
|
||||
__typename: 'Item',
|
||||
id: 'dqdBHJGgjgjg',
|
||||
text: 'test',
|
||||
done: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
我们刚刚为缓存数据添加了一个 `todoItems` 数组,并定义了其中每项的类型名称为 `Item`(在我们的本地 schema 中指定)。
|
||||
|
||||
## 查询本地数据
|
||||
|
||||
查询本地缓存与 [将 GraphQL 查询发送到远程服务器](apollo/queries.md) 非常相似。首先,我们需要创建一个查询:
|
||||
|
||||
```js
|
||||
// App.vue
|
||||
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
const todoItemsQuery = gql`
|
||||
{
|
||||
todoItems @client {
|
||||
id
|
||||
text
|
||||
done
|
||||
}
|
||||
}
|
||||
`;
|
||||
```
|
||||
|
||||
`@client` 指令是与发送到远程 API 的查询的主要区别。该指令指定 Apollo 客户端不应在远程 GraqhQL API 上执行此查询,而是应该从本地缓存中获取结果。
|
||||
|
||||
现在,我们可以在 Vue 组件中像普通的 Apollo 查询一样使用此查询:
|
||||
|
||||
```js
|
||||
// App.vue
|
||||
|
||||
apollo: {
|
||||
todoItems: {
|
||||
query: todoItemsQuery
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
## 使用变更修改本地数据
|
||||
|
||||
我们有两种不同的方法来修改本地数据:
|
||||
|
||||
- 使用 `writeData` 方法直接写入,就像我们在 [缓存初始化](#initializing-an-apollo-cache) 时所做的那样;
|
||||
- 调用一个 GraphQL 变更。
|
||||
|
||||
让我们在 [本地 GraphQL schema](#creating-a-local-schema) 中添加一些变更:
|
||||
|
||||
```js{10-14}
|
||||
// main.js
|
||||
|
||||
export const typeDefs = gql`
|
||||
type Item {
|
||||
id: ID!
|
||||
text: String!
|
||||
done: Boolean!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
checkItem(id: ID!): Boolean
|
||||
addItem(text: String!): Item
|
||||
}
|
||||
`;
|
||||
```
|
||||
|
||||
`checkItem` 变更会将某一事项的 `done` 属性设置为相反的布尔值。让我们用 `gql` 创建它:
|
||||
|
||||
```js
|
||||
// App.vue
|
||||
|
||||
const checkItemMutation = gql`
|
||||
mutation($id: ID!) {
|
||||
checkItem(id: $id) @client
|
||||
}
|
||||
`;
|
||||
```
|
||||
|
||||
我们定义了一个**本地**变更(因为在这里写了一个 `@client` 指令),它将接受一个唯一的标识符作为参数。现在,我们需要一个**解析器**:一个解析 schema 中类型或字段的值的函数。
|
||||
|
||||
在我们的例子中,解析器将定义当我们执行了变更时会对本地 Apollo 缓存做出哪些更改。本地解析器具有与远程解析器相同的功能签名(`(parent, args, context, info) => data`)。事实上,我们只需要使用 args(传递给变更的参数)和 context(我们需要它的缓存属性来读写数据)。
|
||||
|
||||
让我们在主文件中添加一个解析器:
|
||||
|
||||
```js
|
||||
// main.js
|
||||
|
||||
const resolvers = {
|
||||
Mutation: {
|
||||
checkItem: (_, { id }, { cache }) => {
|
||||
const data = cache.readQuery({ query: todoItemsQuery });
|
||||
const currentItem = data.todoItems.find(item => item.id === id);
|
||||
currentItem.done = !currentItem.done;
|
||||
cache.writeQuery({ query: todoItemsQuery, data });
|
||||
return currentItem.done;
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
在这里我们做了什么?
|
||||
|
||||
1. 从缓存中读取 `todoItemsQuery` 以查看我们现在拥有的 `todoItems`;
|
||||
2. 查找具有给定 id 的事项;
|
||||
3. 将找到的事项的 `done` 属性改为相反的值;
|
||||
4. 将我们更改的 `todoItems` 写回缓存;
|
||||
5. 将 `done` 属性作为变更的结果返回。
|
||||
|
||||
现在我们需要用新创建的 `resolvers` 替换 Apollo 客户端选项中的空 `resolvers` 对象:
|
||||
|
||||
```js{17}
|
||||
// main.js
|
||||
|
||||
const resolvers = {
|
||||
Mutation: {
|
||||
checkItem: (_, { id }, { cache }) => {
|
||||
const data = cache.readQuery({ query: todoItemsQuery });
|
||||
const currentItem = data.todoItems.find(item => item.id === id);
|
||||
currentItem.done = !currentItem.done;
|
||||
cache.writeQuery({ query: todoItemsQuery, data });
|
||||
return currentItem.done;
|
||||
},
|
||||
};
|
||||
|
||||
const apolloClient = new ApolloClient({
|
||||
cache,
|
||||
typeDefs,
|
||||
resolvers,
|
||||
});
|
||||
```
|
||||
|
||||
现在,我们可以在 Vue 组件中像普通的 Apollo [变更](apollo/mutations.md) 一样使用此变更:
|
||||
|
||||
```js
|
||||
// App.vue
|
||||
|
||||
methods: {
|
||||
checkItem(id) {
|
||||
this.$apollo.mutate({
|
||||
mutation: checkItemMutation,
|
||||
variables: { id }
|
||||
});
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
@@ -3,12 +3,52 @@
|
||||
如果你的应用需要连接到不同的 GraphQL 入口端点,你可以指定多个 apollo 客户端:
|
||||
|
||||
```js
|
||||
const apolloProvider = new VueApollo({
|
||||
clients: {
|
||||
a: apolloClient,
|
||||
b: otherApolloClient,
|
||||
},
|
||||
defaultClient: apolloClient,
|
||||
const defaultOptions = {
|
||||
// 你可以使用 `wss` 进行安全连接(在生产环境中推荐)
|
||||
// 使用 `null` 来禁用订阅
|
||||
wsEndpoint: process.env.VUE_APP_GRAPHQL_WS || 'ws://localhost:4000/graphql',
|
||||
// LocalStorage 令牌
|
||||
tokenName: AUTH_TOKEN,
|
||||
// 使用 Apollo Engine 启用自动查询持久化
|
||||
persisting: false,
|
||||
// 在所有情形下都使用 websockets(没有 HTTP)
|
||||
// 你需要传递一个 `wsEndpoint` 来让它运作
|
||||
websocketsOnly: false,
|
||||
// 是否已在服务端被渲染?
|
||||
ssr: false,
|
||||
}
|
||||
|
||||
const clientAOptions = {
|
||||
// 你可以使用 `https` 进行安全连接(在生产环境中推荐)
|
||||
httpEndpoint: 'http://localhost:4000/graphql',
|
||||
}
|
||||
|
||||
const clientBOptions = {
|
||||
httpEndpoint: 'http://example.org/graphql',
|
||||
}
|
||||
|
||||
// 在 Vue 应用程序文件中调用此方法
|
||||
export function createProvider (options = {}) {
|
||||
const createA= createApolloClient({
|
||||
...defaultOptions,
|
||||
...clientAOptions,
|
||||
});
|
||||
|
||||
const createB = createApolloClient({
|
||||
...defaultOptions,
|
||||
...clientBptions,
|
||||
});
|
||||
|
||||
const a = createA.apolloClient;
|
||||
const b = createB.apolloClient;
|
||||
|
||||
// 创建 vue apollo provider
|
||||
const apolloProvider = new VueApollo({
|
||||
clients: {
|
||||
a,
|
||||
b
|
||||
}
|
||||
defaultClient: a,
|
||||
})
|
||||
```
|
||||
|
||||
@@ -29,4 +69,4 @@ tags: {
|
||||
query: gql`...`,
|
||||
client: 'b',
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user