美文网首页vue
关于vue和apollo-client的结合(一)

关于vue和apollo-client的结合(一)

作者: rithe | 来源:发表于2018-07-27 18:10 被阅读361次

基础版

1、先来看看最基础的配置

import {ApolloClient} from 'apollo-client'
import {createHttpLink} from 'apollo-link-http'
import {InMemoryCache} from 'apollo-cache-inmemory'
import {ApolloLink} from 'apollo-link'
import vue from 'vue'

const httpLink = createHttpLink({
  uri: 'https://www.baidu.com/graphql'  //配置api调用连接
})

const middlewareLink = new ApolloLink((operation, forward) => {
  operation.setContext({
    headers: {
      'access-token': sessionStorage.getItem('access-token') || null
    }
  })  //request拦截器

  return forward(operation).map(response => {
    return response
  })  //response拦截器,但是此处并不能对错误响应进行拦截
})

const authLink = middlewareLink.concat(httpLink)

const defaultOptions = {
  watchQuery: {
    fetchPolicy: 'network-only',
    errorPolicy: 'ignore'
  },
  query: {
    fetchPolicy: 'network-only',
    errorPolicy: 'all'
  }
}

const apollo = new ApolloClient({
  link: authLink,
  cache: new InMemoryCache(),
  connectToDevTools: true,
  defaultOptions: defaultOptions
})

export default apollo

2、如果在请求需要带入cookie, 需要配置credentials参数

const httpLink = createHttpLink({
  uri: 'https://www.baidu.com/graphql',
  credentials: 'include'
})

升级版

1、加入错误响应拦截器

npm install apollo-link-error --save
const errorLink = onError(({networkError, response}) => {
  let errorMsg = ''
  if (!!response && response.errors !== undefined && response.errors.length) {
    errorMsg = !response.errors[0].message ? '服务器错误' : response.errors[0].message
  }
  if (!!networkError) {
    errorMsg = networkError.message
    if (networkError.result !== undefined) {
      errorMsg = networkError.result.success === false ? networkError.result.message : networkError.result.error
    }
  }
  if (!!errorMsg) {
    vue.prototype.$alert(errorMsg) //用vue的ale
  }
})

2、在前端apollo-client默认是不支持联合查询的。如果我们的graphql中存在如下的语法

...on A{
       name
 }
...on B{
      name
}

浏览器中就会报错

You are using the simple (heuristic) fragment matcher, but your queries contain union or interface types.
Apollo Client will not be able to able to accurately map fragments.To make this error go away, 
use the IntrospectionFragmentMatcher as described in the docs: 
https://www.apollographql.com/docs/react/recipes/fragment-matching.html

解决方法如下,加入如下配置

const fragmentMatcher = new IntrospectionFragmentMatcher({
  introspectionQueryResultData: {
    __schema: {
      types: [
        {
          kind: 'INTERFACE',
          name: 'Document',
          possibleTypes: [
            {name: 'MyInterface1'},
            {name: 'SomeInterface2'}
          ]
        }
      ]
    }
  }
})

最终版

完整配置

import {ApolloClient} from 'apollo-client'
import {createHttpLink} from 'apollo-link-http'
import {InMemoryCache, IntrospectionFragmentMatcher} from 'apollo-cache-inmemory'
import {ApolloLink} from 'apollo-link'
import {onError} from 'apollo-link-error'
import vue from 'vue'

const httpLink = createHttpLink({
  uri: 'https://www.baidu.com/graphql',
  credentials: 'include'
})

const middlewareLink = new ApolloLink((operation, forward) => {
  operation.setContext({
    headers: {
      'access-token': sessionStorage.getItem('access-token') || null
    }
  })

  return forward(operation).map(response => {
    return response
  })
})

const errorLink = onError(({networkError, response}) => {
  let errorMsg = ''
  if (!!response && response.errors !== undefined && response.errors.length) {
    errorMsg = !response.errors[0].message ? '服务器错误' : response.errors[0].message
  }
  if (!!networkError) {
    errorMsg = networkError.message
    if (networkError.result !== undefined) {
      errorMsg = networkError.result.success === false ? networkError.result.message : networkError.result.error
    }
  }
  if (!!errorMsg) {
    vue.prototype.$alert(errorMsg)
  }
})

const authLink = middlewareLink.concat(httpLink)

const defaultOptions = {
  watchQuery: {
    fetchPolicy: 'network-only',
    errorPolicy: 'ignore'
  },
  query: {
    fetchPolicy: 'network-only',
    errorPolicy: 'all'
  }
}

const fragmentMatcher = new IntrospectionFragmentMatcher({
  introspectionQueryResultData: {
    __schema: {
      types: [
        {
          kind: 'INTERFACE',
          name: 'Document',
          possibleTypes: [
            {name: 'MyInterface1'},
            {name: 'SomeInterface2'}
          ]
        }
      ]
    }
  }
})

const apollo = new ApolloClient({
  link: errorLink.concat(authLink),
  cache: new InMemoryCache({fragmentMatcher}),
  connectToDevTools: true,
  defaultOptions: defaultOptions
})

export default apollo

相关文章

  • 关于vue和apollo-client的结合(一)

    基础版 1、先来看看最基础的配置 2、如果在请求需要带入cookie, 需要配置credentials参数 升级版...

  • vue集合elementui日期插件

    elementui日期插件和vue结合

  • DRF + VUE 开发流程

    转载手把手Django+Vue前后端分离开发入门(附demo)Vue-cli3和Django本地结合教程 结合两者...

  • 2019-11-28

    关于mockjs模拟数据的使用 一、 本文主要结合webpack+vue+mockjs,前后端分离,模拟后端接口数...

  • Vue 学习笔记 (一)

    目的:本教程将结合flask和vue制作一个前后端分离的网站 1. vue 相关操作指令 2. vue 启动顺序 ...

  • vue 组件和路由

    === Vue组件Vue组件的创建vue.extend结合vue.component创建vue.component...

  • 关于数据的格式验证(不限于表单)

    网上关于数据验证的主要都是基于表单,而且很多是跟JQ结合,个人不太喜欢,最近写vue项目比较多,基于vue的数据验...

  • Vue中的动画

    Vue动画 Vue动画API 定义不同的名称动画 第三方动画库Animate.css和Vue的结合使用 enter...

  • vue-router基础

    Vue-router学习指南 日记:本文按照vue-router官网的知识结合例子进行分析和讲解,搭建工具(vue...

  • Electron-vue创建

    1. 初始化项目 electron-vue 是 vue-cli 和 electron 结合的项目,比单独使用 vu...

网友评论

    本文标题:关于vue和apollo-client的结合(一)

    本文链接:https://www.haomeiwen.com/subject/rwkgmftx.html