Vue-apollo — 在Vue-cli项目中使用Graphql

<h1 id="articleHeader0"><a href="http://www.js-code.com/tag/vue" title="Vue" target="_blank">Vue</a>-apollo — 在<a href="http://www.js-code.com/tag/vue" title="Vue" target="_blank">Vue</a>-cli项目中使用Graphql</h1> <blockquote><p>Vue-apollo — Integrates <a href="https://www.apollographql.com/" rel="nofollow noreferrer" target="_blank">apollo</a> in your <a href="http://vuejs.org/" rel="nofollow noreferrer" target="_blank">Vue</a> components with declarative queries.</p></blockquote> <p>当然我们可以通过直接在url中携带参数直接请求,这样太过麻烦。vue-apollo为我们提供了一整套解决方案,可以解决大部分问题。</p> <p>本篇文章将介绍如何在你的vue-cli项目中简单使用vue-apollo和一些目前遇到的小坑。</p> <h2 id="articleHeader1">安装</h2> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="npm install --save vue-apollo graphql apollo-client apollo-link apollo-link-http apollo-cache-inmemory graphql-tag" title="" data-original-title="复制"></span> </div> </p></div> <pre class="shell hljs"><code class="shell" style="word-break: break-word; white-space: initial;">npm install --save vue-apollo graphql apollo-client apollo-link apollo-link-http apollo-cache-inmemory graphql-tag</code></pre> <p>创建<code>ApolloClient</code>实例, 安装<code>VueApollo</code>插件</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="import Vue from 'vue' import { ApolloClient } from 'apollo-client' import { HttpLink } from 'apollo-link-http' import { InMemoryCache } from 'apollo-cache-inmemory' import VueApollo from 'vue-apollo' const httpLink = new HttpLink({ // You should use an absolute URL here uri: 'http://localhost:3020/graphql', }) // Create the apollo client const apolloClient = new ApolloClient({ link: httpLink, cache: new InMemoryCache(), connectToDevTools: true, }) // Install the vue plugin Vue.use(VueApollo)" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"><span class="hljs-keyword">import</span> Vue <span class="hljs-keyword">from</span> <span class="hljs-string">'vue'</span> <span class="hljs-keyword">import</span> { ApolloClient } <span class="hljs-keyword">from</span> <span class="hljs-string">'apollo-client'</span> <span class="hljs-keyword">import</span> { HttpLink } <span class="hljs-keyword">from</span> <span class="hljs-string">'apollo-link-http'</span> <span class="hljs-keyword">import</span> { InMemoryCache } <span class="hljs-keyword">from</span> <span class="hljs-string">'apollo-cache-inmemory'</span> <span class="hljs-keyword">import</span> VueApollo <span class="hljs-keyword">from</span> <span class="hljs-string">'vue-apollo'</span> <span class="hljs-keyword">const</span> httpLink = <span class="hljs-keyword">new</span> HttpLink({ <span class="hljs-comment">// You should use an absolute URL here</span> uri: <span class="hljs-string">'http://localhost:3020/graphql'</span>, }) <span class="hljs-comment">// Create the apollo client</span> <span class="hljs-keyword">const</span> apolloClient = <span class="hljs-keyword">new</span> ApolloClient({ <span class="hljs-attr">link</span>: httpLink, <span class="hljs-attr">cache</span>: <span class="hljs-keyword">new</span> InMemoryCache(), <span class="hljs-attr">connectToDevTools</span>: <span class="hljs-literal">true</span>, }) <span class="hljs-comment">// Install the vue plugin</span> Vue.use(VueApollo)</code></pre> <p><strong>如果你开启了vue-cli提供的代理, 这里同样适用.</strong></p> <h2 id="articleHeader2">创建PROVIDER</h2> <p>就像<code>vue-router</code>与<code>vuex</code>一样, 需要将<code>apolloProvider</code>添加为根组件.</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="const apolloProvider = new VueApollo({ defaultClient: apolloClient, }) new Vue({ el: '#app', provide: apolloProvider.provide(), render: h => h(App),<br /> })&#8221; title=&#8221;&#8221; data-original-title=&#8221;复制&#8221;></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"><span class="hljs-keyword">const</span> apolloProvider = <span class="hljs-keyword">new</span> VueApollo({ <span class="hljs-attr">defaultClient</span>: apolloClient, }) <span class="hljs-keyword">new</span> Vue({ <span class="hljs-attr">el</span>: <span class="hljs-string">'#app'</span>, <span class="hljs-attr">provide</span>: apolloProvider.provide(), <span class="hljs-attr">render</span>: <span class="hljs-function"><span class="hljs-params">h</span> =&gt;</span> h(App), })</code></pre> <h2 id="articleHeader3">quasar-cli 中安装</h2> <p>如果你不了解<a href="http://quasar-framework.org/" rel="nofollow noreferrer" target="_blank">Quasar Framework</a>并且不打算使用, 这段可以跳过.</p> <p>在<code>plugins</code>目录中创建新的js文件, 并在 <code>quasar.conf.js</code> 中加入它. </p> <p>打开创建好的文件:</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="import {ApolloClient} from 'apollo-client' import {HttpLink} from 'apollo-link-http' import {InMemoryCache} from 'apollo-cache-inmemory' import VueApollo from 'vue-apollo' // Create the apollo provider const apolloProvider = new VueApollo({ defaultClient: new ApolloClient({ link: new HttpLink({ // You should use an absolute URL here uri: 'http://localhost:3020/graphql', }), cache: new InMemoryCache(), connectToDevTools: true }) }) // leave the export, even if you don't use it export default ({ app, Vue }) => {<br /> // something to do<br /> Vue.use(VueApollo)<br /> app.provide = apolloProvider.provide()<br /> }&#8221; title=&#8221;&#8221; data-original-title=&#8221;复制&#8221;></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"><span class="hljs-keyword">import</span> {ApolloClient} <span class="hljs-keyword">from</span> <span class="hljs-string">'apollo-client'</span> <span class="hljs-keyword">import</span> {HttpLink} <span class="hljs-keyword">from</span> <span class="hljs-string">'apollo-link-http'</span> <span class="hljs-keyword">import</span> {InMemoryCache} <span class="hljs-keyword">from</span> <span class="hljs-string">'apollo-cache-inmemory'</span> <span class="hljs-keyword">import</span> VueApollo <span class="hljs-keyword">from</span> <span class="hljs-string">'vue-apollo'</span> <span class="hljs-comment">// Create the apollo provider</span> <span class="hljs-keyword">const</span> apolloProvider = <span class="hljs-keyword">new</span> VueApollo({ <span class="hljs-attr">defaultClient</span>: <span class="hljs-keyword">new</span> ApolloClient({ <span class="hljs-attr">link</span>: <span class="hljs-keyword">new</span> HttpLink({ <span class="hljs-comment">// You should use an absolute URL here</span> uri: <span class="hljs-string">'http://localhost:3020/graphql'</span>, }), <span class="hljs-attr">cache</span>: <span class="hljs-keyword">new</span> InMemoryCache(), <span class="hljs-attr">connectToDevTools</span>: <span class="hljs-literal">true</span> }) }) <span class="hljs-comment">// leave the export, even if you don't use it</span> <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ({ app, Vue }) =&gt; { <span class="hljs-comment">// something to do</span> Vue.use(VueApollo) app.provide = apolloProvider.provide() }</code></pre> <h2 id="articleHeader4">使用</h2> <h3 id="articleHeader5">query</h3> <p>需要提前在组件中定义graphql字符串.</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="<script> import gql from &quot;graphql-tag&quot;; <a href="http://www.js-code.com/tag/export" title="export" target="_blank">export</a> default { data() { return {hello:&#8221;,loading:0}; }, apollo: { hello: { query() { return gql`{hello}` }, loadingKey: &quot;loading&quot; } } }; </script>&#8221; title=&#8221;&#8221; data-original-title=&#8221;复制&#8221;></span> </div> </p></div> <pre class="hljs xml"><code class="vue"><span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript"> <span class="hljs-keyword">import</span> gql <span class="hljs-keyword">from</span> <span class="hljs-string">"graphql-tag"</span>; <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> { data() { <span class="hljs-keyword">return</span> {<span class="hljs-attr">hello</span>:<span class="hljs-string">''</span>,<span class="hljs-attr">loading</span>:<span class="hljs-number">0</span>}; }, <span class="hljs-attr">apollo</span>: { <span class="hljs-attr">hello</span>: { query() { <span class="hljs-keyword">return</span> gql<span class="hljs-string">`{hello}`</span> }, <span class="hljs-attr">loadingKey</span>: <span class="hljs-string">"loading"</span> } } }; </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></code></pre> <p>data中必须提前创建apollo中相应字段且字段名必须相同. </p> <p>通过gql创建graphql字符串, <strong>特别注意:</strong>使用 <code>query(){return gql</code>` }<code> 用来创建需要计算得到的字符串, 如字符串中携带</code>${<a href="http://www.js-code.com/tag/this" title="this" target="_blank">this</a>.hello}<code>等. 纯字符串可用</code>query:gql<code>` </code>直接创建.</p> <p>loadingKey指定data中创建的字段, 用于表示状态,<code> loadingKey</code>应为初始值为0的整数. 处于加载状态时会执行<code>loadingKey++</code>操作, 加载结束会执行<code>loadingKey—</code>操作.</p> <h3 id="articleHeader6">mutation</h3> <p>随时使用, 不需要提前声明或定义. 请求结果为一个promise.</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="this.$apollo.mutate({ // Query mutation: gql`mutation ($label: String!) { addTag(label: $label) { id label } }`, // Parameters variables: { label: this.newTag, } }).then(data=>{<br /> console.log(data)<br /> }).catch(error=>{<br /> console.log(error)<br /> })<br /> &#8221; title=&#8221;&#8221; data-original-title=&#8221;复制&#8221;></span> </div> </p></div> <pre class="javascript hljs"><code class="javascript"><span class="hljs-keyword">this</span>.$apollo.mutate({ <span class="hljs-comment">// Query</span> mutation: gql<span class="hljs-string">`mutation ($label: String!) { addTag(label: $label) { id label } }`</span>, <span class="hljs-comment">// Parameters</span> variables: { <span class="hljs-attr">label</span>: <span class="hljs-keyword">this</span>.newTag, } }).then(<span class="hljs-function"><span class="hljs-params">data</span>=&gt;</span>{ <span class="hljs-built_in">console</span>.log(data) }).catch(<span class="hljs-function"><span class="hljs-params">error</span>=&gt;</span>{ <span class="hljs-built_in">console</span>.log(error) }) </code></pre> <p>并没有<code>mutation(){return gql</code>`}<code> 这样的操作, 所以计算属性需要通过 </code>variables`传入. 当然这种方法也适用于query.</p> <h3 id="articleHeader7">数据更新</h3> <p>一般的, 在组件创建时会发起一次query请求. 如果需要重新请求数据:<code><a href="http://www.js-code.com/tag/this" title="this" target="_blank">this</a>.$apollo.queries.&lt;$name&gt;.refetch()</code></p> <p>如 <code>this.$apollo.queries.hello.refetch()</code> 请求指定字段.</p> <p>请求发起后<code>loadingKey</code>也将重新计算.</p>
脚本宝典为你提供优质服务
脚本宝典 » Vue-apollo — 在Vue-cli项目中使用Graphql

发表评论

提供最优质的资源集合

立即查看 了解详情