apollo
@nuxtjs/apollo

使用 vue-apollo 在您的 Nuxt 應用程式中整合 GraphQL。

NuxtJS 中的 Apollo

npm version license

警告

此版本需要支援 serverPrefetch 的 Vue 2.6+。例如

有時您可能需要刪除/重建 package-lock.json/yarn.lock 才能使其工作。

設定

1- 安裝 apollo 模組

npm install --save @nuxtjs/apollo

yarn add @nuxtjs/apollo

2- 載入 @nuxtjs/apollo 模組

// nuxt.config.js

export default {
  modules: [
    '@nuxtjs/apollo',
  ],

  apollo: {
    clientConfigs: {
      default: {
        httpEndpoint: 'https://:4000',
      }
    }
  }
}

3- 載入 *.gql*.graphql 檔案 (可選)

安裝 graphql-tag

npm install --save graphql-tag

yarn add graphql-tag

⚠️ Typescript 使用者

在您的原始檔夾中新增一個 gql.d.ts 檔案,其內容如下

declare module '*.gql' {
  import { DocumentNode } from 'graphql'

  const content: DocumentNode
  export default content
}

declare module '*.graphql' {
  import { DocumentNode } from 'graphql'

  const content: DocumentNode
  export default content
}

使用

您已成功在專案中啟用 vue-apollo

有關如何在您的應用程式中使用 vue-apollo 的更多資訊,請檢視 官方示例vue-apollo 官方文件

高階配置

{
  // Add apollo module
  modules: ['@nuxtjs/apollo'],

  apollo: {
    // Sets up the apollo client endpoints
    clientConfigs: {
      // recommended: use a file to declare the client configuration (see below for example)
      default: '~/plugins/my-alternative-apollo-config.js',

      // you can setup multiple clients with arbitrary names
      alternativeClient: {
        // required
        httpEndpoint: 'https://:4000',

        // override HTTP endpoint in browser only
        browserHttpEndpoint: '/graphql',

        // See https://www.apollographql.com/docs/link/links/http.html#options
        httpLinkOptions: {
          credentials: 'same-origin'
        },

        // You can use `wss` for secure connection (recommended in production)
        // Use `null` to disable subscriptions
        wsEndpoint: 'ws://:4000',

        // LocalStorage token
        tokenName: 'apollo-token',

        // Enable Automatic Query persisting with Apollo Engine
        persisting: false,

        // Use websockets for everything (no HTTP)
        // You need to pass a `wsEndpoint` for this to work
        websocketsOnly: false
      },
    },
    
    /**
     * default 'apollo' definition
     */
    defaultOptions: {
      // See 'apollo' definition
      // For example: default query options
      $query: {
        loadingKey: 'loading',
        fetchPolicy: 'cache-and-network',
      },
    },
    
    // setup a global query loader observer (see below for example)
    watchLoading: '~/plugins/apollo-watch-loading-handler.js',
    
    // setup a global error handler (see below for example)
    errorHandler: '~/plugins/apollo-error-handler.js',

    // Sets the authentication type for any authorized request.
    authenticationType: 'Bearer', 

    // Token name for the cookie which will be set in case of authentication
    tokenName: 'apollo-token',

    // [deprecated] Enable the graphql-tag/loader to parse *.gql/*.graphql files
    includeNodeModules: true,

    // Cookie parameters used to store authentication token
    cookieAttributes: {
      /**
        * Define when the cookie will be removed. Value can be a Number
        * which will be interpreted as days from time of creation or a
        * Date instance. If omitted, the cookie becomes a session cookie.
        */
      expires: 7,

      /**
        * Define the path where the cookie is available. Defaults to '/'
        */
      path: '/',

      /**
        * Define the domain where the cookie is available. Defaults to
        * the domain of the page where the cookie was created.
        */
      domain: 'example.com',

      /**
        * A Boolean indicating if the cookie transmission requires a
        * secure protocol (https). Defaults to false.
        */
      secure: false,
    },
  }
}

使用檔案配置的 Apollo clientOptions

⚠️ 如果您需要在 apollo 配置中宣告函式(例如 getAuthinMemoryCacheOptions.fragmentMatcher),您 必須 使用外部檔案定義您的 clientOptions

// ~/plugins/my-alternative-apollo-config.js

export default (context) => {
  return {
    httpEndpoint: 'https://:4000/graphql-alt',

    /*
     * For permanent authentication provide `getAuth` function.
     * The string returned will be used in all requests as authorization header
     */
    getAuth: () => 'Bearer my-static-token',
  }
}

watchLoading 示例

// ~/plugins/apollo-watch-loading-handler.js

export default (isLoading, countModifier, nuxtContext) => {
  loading += countModifier
  console.log('Global loading', loading, countModifier)
}

errorHandler 示例

// ~/plugins/apollo-error-handler.js

export default ({ graphQLErrors, networkError, operation, forward }, nuxtContext) => {
  console.log('Global error handler')
  console.log(graphQLErrors, networkError, operation, forward)
}

選項

您可以(在一個簡單的設定中)像上面描述的那樣新增一個物件。如果您需要覆蓋快取或預設的 getAuth() 函式,則使用指向您的配置檔案路徑,該檔案返回客戶端配置選項。

clientConfigs Option: 必需

設定 apollo 客戶端端點。您可以在 此處 找到每個端點的所有可用選項

檢視 官方 vue-apollo-cli,其中介紹了可能的用例。

clientConfigs.default Object: 必需

clientConfigs. Object|Path: 可選

tokenName String: 可選,預設值: 'apollo-token'

身份驗證時將設定在 cookie 中的令牌名稱。您還可以在每個 clientConfigs 中提供一個 tokenName 選項以覆蓋預設值。每次發出請求時,此 cookie 中的值將以 "Authorization" HTTP 標頭形式傳送,具體格式由下面的 authenticationType 指定。

authenticationType String: 可選,預設值: 'Bearer'

設定任何授權請求的身份驗證型別。如果您的 GraphQL API 所需的身份驗證型別不是預設的 Bearer,請修改此項。所有請求都將以適當的 HTTP 標頭格式傳送: "Authorization "(例如 Authorization: Bearer abc123)。

如果您的後端要求 Authorization 標頭格式為 "Authorization",沒有任何字首,那麼您應該將此值設定為空字串。

includeNodeModules Boolean: 可選,預設值: false

如果您在 node_module 資料夾中使用 *.gql 檔案,您可以啟用 graphql-tag/loader 為您解析檔案。

身份驗證

您可以使用以下身份驗證方法

 // set your graphql-token
 this.$apolloHelpers.onLogin(token /* if not default you can pass in client as second argument, you can set custom cookies attributes object as the third argument, and you can skip reset store as the fourth argument */)
 // unset your graphql-token
 this.$apolloHelpers.onLogout(/* if not default you can pass in client as first argument, and you can skip reset store as the second argument */)
 // get your current token (we persist token in a cookie)
 this.$apolloHelpers.getToken(/* you can provide named tokenName if not 'apollo-token' */)

檢視 完整示例

使用者登入

// ~/components/my-component.js

export default {
  methods: {
    async onSubmit () {
      const credentials = this.credentials
      try {
          const res = await this.$apollo.mutate({
              mutation: authenticateUserGql,
              variables: credentials
          }).then(({data}) => data && data.authenticateUser)
          await this.$apolloHelpers.onLogin(res.token)
      } catch (e) {
          console.error(e)
      }
    },
  }
}

使用者登出

// ~/components/my-component.js

export default {
  methods: {
    async onLogout () {
      await this.$apolloHelpers.onLogout()
    },
  }
}

getToken

// ~/middleware/isAuth.js

export default ({app, error}) => {
  const hasToken = !!app.$apolloHelpers.getToken()
  if (!hasToken) {
    error({
      errorCode:503, 
      message:'You are not allowed to see this'
    })
  }
}

訪問您的 apolloProvider 的 defaultClient 的示例

Vuex actions
// ~/store/my-store.js

export default {
  actions: {
    foo (store, payload) {
      let client = this.app.apolloProvider.defaultClient
    }
  }
}
頁面元件的 asyncData/fetch 方法
// ~/components/my-component.js

export default {
  asyncData (context) {
    let client = context.app.apolloProvider.defaultClient
  }
}
nuxtServerInit
export default {
  nuxtServerInit (store, context) {
    let client = context.app.apolloProvider.defaultClient
  }
}
在元件內部的任何方法中訪問客戶端或呼叫 mutations 和 queries
// ~/components/my-component.js

export default {
  methods: {
    foo () {
      // receive the associated Apollo client 
      const client = this.$apollo.getClient()

      // most likely you would call mutations like following:
      this.$apollo.mutate({mutation, variables})
      
      // but you could also call queries like this:
      this.$apollo.query({query, variables})
        .then(({ data }) => {
          // do what you want with data
        })
    }
  }
}

一旦您獲取到客戶端,您就可以訪問其方法和屬性。請參閱 API 參考

任何元件上的智慧查詢

// nuxt.config.js

export default {
  apollo: {
    foo: {
      query: fooGql,
      variables () {
        return {
          myVar: this.myVar
        }
      }
    }
  }
}

有關智慧查詢的更多資訊,請參閱 vue-apollo 文件

在 node_modules 中新增 GQL 檔案識別

// nuxt.config.js

export default {
  apollo: {
    clientConfigs: {
      default: '~/apollo/client-configs/default.js'
    },
    includeNodeModules: true
  }
}

升級

apollo-module v3 => v4 升級指南

此模組的第 4 版提供零配置。這意味著我們使用 vue-cli-plugin-apollo 中可用的最佳方法和相同的配置行為。這意味著您無需自行配置,只需傳遞

按如下方式編輯您的配置

// nuxt.config.js

export default {
  apollo: {
    clientConfigs: {
      default:{
        httpEndpoint: YOUR_ENDPOINT,
        wsEndpoint: YOUR_WS_ENDPOINT
      }
    }
  }
}

apollo-client v1 => v2 升級指南

此模組的第 3 版使用 apollo-client 2.x。您需要確保根據 apollo-client 的升級指南更新所有中介軟體/後置件。請檢視此來源以獲取參考:https://www.apollographql.com/docs/apollo-server/migration-two-dot/

故障排除

代理

CORS 錯誤通常透過代理解決。如果您在客戶端控制檯中看到 Cross-Origin-Request 錯誤,請考慮設定代理。檢視 https://github.com/nuxt-community/proxy-module 以獲取快速直接的設定。

ctx.req.session - req 未定義

這只是一個佔位符。您需要將其替換為您選擇用於儲存令牌的任何儲存機制。這是一個使用本地儲存的示例:https://github.com/Akryum/vue-apollo/issues/144

貢獻和配置設定

在根資料夾的 .env 檔案中設定所需欄位

# cat .env
HTTP_ENDPOINT=https://your-endpoint
WS_ENDPOINT=wss://your-endpoint

index.vue 中,登入過程要求 gql 端點啟用一個返回有效令牌的 mutation

mutation authenticateUser($email:String!,$password:String!){
    authenticateUser(email: $email, password: $password) {
        token
        id
    }
}

如果您的 gql 後端已準備就緒,請按如下方式執行 nuxt

npm install
npm run dev