将 Apollo / GraphQL 与 Vue.js 结合使用

GraphQL最近以暴风雨袭击了世界,最初用于Facebook的专门用例,它已经蔓延到整个开发场景中,成为目前最受欢迎的客户端服务器数据传输方法。在GraphQL创新的最前沿是 Apollo,一个独立的系统组合来创建GraphQL客户端和服务器。今天,我们将学习如何使用Vue.js与apollo客户端2集成。

安装

现在,不幸的是,apollo客户端有许多依赖性,可能是一个痛苦的设置,我会让你通过它。

1# Yarn
2$ yarn vue-apollo graphql apollo-client apollo-link apollo-link-http apollo-link-context apollo-cache-inmemory graphql-tag
3# NPM
4$ npm install --save vue-apollo graphql apollo-client apollo-link apollo-link-http apollo-link-context apollo-cache-inmemory graphql-tag

使用

最有可能的是,如果您打算将 GraphQL / Apollo 添加到 Vue 中,您已经设置了一个项目,但如果不是,我们在这里做的将基于 webpack-simple 模板。

现在我们必须在 main.js 中设置 Apollo. 有几个步骤值得解释,所以我会把它分成碎片。

 1[label main.js (Imports)]
 2import Vue from 'vue';
 3import App from './App.vue';
 4
 5// This is everything we need to work with Apollo 2.0.
 6import { ApolloClient } from 'apollo-client';
 7import { HttpLink } from 'apollo-link-http';
 8import { InMemoryCache } from 'apollo-cache-inmemory';
 9import VueApollo from 'vue-apollo';
10
11// Register the VueApollo plugin with Vue.
12Vue.use(VueApollo);

现在,我们必须为Apollo创建HTTP链接。Apollo 2.0被设计为具有可插入的运输 / 链接系统,因此您可以从websockets或其他运输方式上加载GraphQL API。

1[label main.js (Apollo Link)]
2// Create a new HttpLink to connect to your GraphQL API.
3// According to the Apollo docs, this should be an absolute URI.
4const httpLink = new HttpLink({
5  uri: `https://somerandomgraphqlapi.com/api`
6});
7
8// I'm creating another variable here just because it makes it easier to add more links in the future.
9const link = httpLink;

一旦完成,我们需要设置阿波罗客户端。

 1[label main.js (Apollo Client)]
 2// Create the apollo client
 3const apolloClient = new ApolloClient({
 4  // Tells Apollo to use the link chain with the http link we set up.
 5  link,
 6  // Handles caching of results and mutations.
 7  cache: new InMemoryCache(),
 8  // Useful if you have the Apollo DevTools installed in your browser.
 9  connectToDevTools: true,
10});

好吧,现在我们需要告诉Vue & VueApollo关于apolloClient。

 1[label main.js (VueApollo Setup)]
 2const apolloProvider = new VueApollo({
 3  // Apollo 2.0 allows multiple clients to be enabled at once.
 4  // Here we select the default (and only) client.
 5  defaultClient: apolloClient,
 6});
 7
 8new Vue({
 9  // Inject apolloProvider for components to use.
10  provide: apolloProvider.provide(),
11  render: h => h(App),
12}).$mount('#app');

这就是你需要在你的Vue应用程序中设置Apollo所需的全部。 请参阅下面的完整代码和一些提示。 在下一节,我们将展示如何使用它。

完整的 main.js

 1import Vue from 'vue';
 2import App from './App.vue';
 3// This is everything we need to work with Apollo 2.0.
 4import { ApolloClient } from 'apollo-client';
 5import { HttpLink } from 'apollo-link-http';
 6import { InMemoryCache } from 'apollo-cache-inmemory';
 7import VueApollo from 'vue-apollo';
 8
 9// Register the VueApollo plugin with Vue.
10Vue.use(VueApollo);
11// Create a new HttpLink to connect to your GraphQL API.
12// According to the Apollo docs, this should be an absolute URI.
13const httpLink = new HttpLink({
14  uri: https://somerandomgraphqlapi.com/api
15});
16// I'm creating another variable here just because it
17// makes it easier to add more links in the future.
18const link = httpLink;
19// Create the apollo client
20const apolloClient = new ApolloClient({
21  // Tells Apollo to use the link chain with the http link we set up.
22  link,
23  // Handles caching of results and mutations.
24  cache: new InMemoryCache(),
25  // Useful if you have the Apollo DevTools installed in your browser.
26  connectToDevTools: true,
27});
28const apolloProvider = new VueApollo({
29  // Apollo 2.0 allows multiple clients to be enabled at once.
30  // Here we select the default (and only) client.
31  defaultClient: apolloClient,
32});

修改 HTTP 标题用于身份验证

例如,为了添加JWT身份验证标题,您可以通过使用setContext添加额外的链接来完成此操作(这就是对apollo-link-context的依赖。

 1[label main.js]
 2// Add this to your Apollo imports.
 3import { setContext } from 'apollo-link-context';
 4
 5...
 6
 7// Create a new Middleware Link using setContext
 8const middlewareLink = setContext(() => ({
 9  headers: {
10    authorization: `Bearer ${HOWEVER_I_GET_MY_JWT}`
11  }
12}));
13
14// Change your link assignment from
15// const link = httpLink;
16// to
17const link = middlewareLink.concat(httpLink);

创建 GraphQL 查询

现在,在您的组件中,您可以创建查询并让它们自动填充组件数据,如下:

 1[label MyComponent.vue]
 2<template>
 3  <p v-if="alligatorGraphQL">From GraphQL: {{alligatorGraphQL.name}}</p>
 4</template>
 5
 6<script>
 7import gql from 'graphql-tag';
 8
 9export default {
10  data() {
11    return {
12      <span class="code-annotation">alligatorGraphQL: null</span>
13    }
14  },
15
16  apollo: {
17    // They key is the name of the data property
18    // on the component that you intend to populate.
19    alligatorGraphQL: {
20      // Yes, this looks confusing.
21      // It's just normal GraphQL.
22      query: gql`
23        query alligatorQuery($input: String!) {
24          getAlligator(uuid: $input) {
25            name
26          }
27        }
28      `,
29
30      variables: {
31        // Some random UUID I generated.
32        input: `03e082be-5e10-4351-a968-5f28d3e50565`
33      },
34
35      // Apollo maps results to the name of the query, for caching.
36      // So to update the right property on the componet, you need to
37      // select the property of the result with the name of the query.
38      update: result => result.getAlligator,
39    }
40  }
41}

(这假定您的服务器侧方案大致如下:)

 1type Alligator {
 2  name: String
 3}
 4
 5type Query {
 6  getAlligator(uuid: String!): Alligator
 7}
 8
 9type Mutation {
10  updateAlligatorName(name: String!): String
11}
12
13schema {
14  query: Query
15  mutation: Mutation
16}

<$>[注] Protip:在 Vue 组件上,几乎任何 `apollo {} 属性都可能具有反应性,因此,如果您想要根据反应性属性更改变量或查询,只需用返回基于组件数据对象的函数替换对象。

创建 GraphQL 突变

让我们继续修改上面的组件,以便我们可以更新Alligator的名称以及阅读它,因此我们需要GraphQL突变。

 1[label MyComponent.vue]
 2<template>
 3  <p>
 4    Alligator Name:
 5    <input type="text" v-if="alligatorGraphQL"
 6      :value="alligatorGraphQL.name" @input="temporaryName = $event.target.value"
 7    />
 8    <button @click="updateName">Update Name</button>
 9  </p>
10</template>
11
12<script>
13import gql from 'graphql-tag';
14
15export default {
16  data() {
17    return {
18      temporaryName: '',
19      alligatorGraphQL: null
20    }
21  },
22
23  apollo: {
24    alligatorGraphQL: {
25      query: gql`
26        query alligatorQuery($input: String!) {
27          getAlligator(uuid: $input) {
28            name
29          }
30        }
31      `,
32
33      variables: {
34        input: `03e082be-5e10-4351-a968-5f28d3e50565`
35      },
36
37      update: result => result.getAlligator,
38    }
39  },
40
41  methods: {
42    updateName() {
43      this.$apollo.mutate({
44        mutation: gql`
45          mutation ($name: String!) {
46            updateAlligatorName(name: $name)
47          }
48        `,
49        variables: { name: this.temporaryName }
50      }).then(mutationResult => {
51        // Do stuff with the result.
52        console.log(`The Alligator's updated name is: ${mutationResult.data.updateAlligatorName}`)
53      });
54
55    }
56  }
57}
58</script>

您可能會注意到,我們正在使用一個暫時變量,而不是 v 模型或雙向結合,這是因為 Apollo 的數據結果只能讀取和不變,所以基本上你從您的 GraphQL 伺服器中得到的任何東西都需要被操縱或作為一個不變的資源處理。

你的突变现在应该开火,并在服务器上做出必要的更改(提供服务器配置正确,即)。

这就是你开始使用Vue和Apollo所需的一切。 有关更多细节,请参阅 apollo-vueApollo的文档。

Published At
Categories with 技术
Tagged with
comments powered by Disqus