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-vue和 Apollo的文档。