graphql 拦截 增加全局loading

import Vue from 'vue'
import VueApollo from 'vue-apollo'
import { Loading } from 'element-ui'
import { ApolloClient } from 'apollo-client'
import { ApolloLink, from } from 'apollo-link'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { onError } from 'apollo-link-error'
import router from '@/router'

Vue.use(VueApollo)

let loadingInstance = null

const errorLink = onError(({ graphQLErrors, networkError }) => {
  if (graphQLErrors) {
    graphQLErrors.forEach(({ message, extensions, locations, path }) => {
      if (extensions.code === '401' || extensions.code === '1001') {
        const element = document.createElement('a')
        element.href = extensions.idaasUrl
        const searchParams = new URLSearchParams(element.search)
        searchParams.append('redirect_url', window.location.href)
        element.search = '?' + searchParams.toString()
        window.location.href = element.href
        return
      }
      if (extensions.code === 6) {
        router.push('/noAccess')
      }
      console.log(
        `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
      )
    })
  }
  if (loadingInstance) {
    loadingInstance.close()
  }
  if (graphQLErrors) {
    graphQLErrors.map(({ message, locations, path }) => {
      console.log(`+++++ [GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`)
    })
  }
  if (networkError) console.log(`[Network error]: ${networkError}`)
})

const loadingLink = new ApolloLink((operation, forward) => {
  operation.setContext({
    headers: {
      authtoken: localStorage.getItem('auth-token-home') || null
    }
  })
  const Arr = ['getSearchArticle']
  if (Arr.includes(operation.operationName)) {
    loadingInstance = Loading.service({
      lock: true,
      fullscreen: true
    })
  }
  return forward(operation)
})

const afterwareLink = new ApolloLink((operation, forward) => {
  const Arr = ['getSearchArticle']
  return forward(operation).map(response => {
    if (Arr.includes(operation.operationName) && loadingInstance) {
      loadingInstance.close()
    }
    return response
  })
})

const httpLink = createHttpLink({
  uri: '/home/graphql'
})

export const apolloClient = new ApolloClient({
  link: from([loadingLink, afterwareLink, errorLink, httpLink]),
  cache: new InMemoryCache({
    addTypename: false
  }),
  defaultOptions: {
    query: {
      fetchPolicy: 'no-cache'
    }
  }
})

export const apolloProvider = new VueApollo({
  defaultClient: apolloClient
})

posted @ 2021-05-20 15:49  yangAL  阅读(215)  评论(0编辑  收藏  举报