@7span/nuxt-apollo-module 中文文档教程

发布于 3年前 浏览 38 项目主页 更新于 3年前

Apollo inside of NuxtJS

npm 版本license

Warning

此版本需要具有 serverPrefetch 支持的 Vue 2.6+。 例如:

npm install --save vue@2.6.6 vue-template-compiler@2.6.6 vue-server-renderer@2.6.6

有时您可能需要删除/重建 package-lock.json/yarn.lock 才能使其正常工作。

Setup

1- Install apollo module

npm install --save @nuxtjs/apollo

yarn add @nuxtjs/apollo

2- Load @nuxtjs/apollo module

// nuxt.config.js

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

  apollo: {
    clientConfigs: {
      default: {
        httpEndpoint: 'http://localhost:4000',
      }
    }
  }
}

3- Loading *.gql or *.graphql files (optional)

安装 graphql-tag

npm install --save graphql-tag

yarn add graphql-tag

:warning: Typescript users

在您的源文件夹中添加一个 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
}

Usage

您已成功启用 vue-apollo 在你的项目中。

查看官方示例vue-apollo 关于如何在你的应用程序中使用 vue-apollo 的官方文档

Advanced configuration

{
  // 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: 'http://localhost: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://localhost: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 using file configuration

:警告:如果你需要声明函数(比如 getAuthinMemoryCacheOptions.fragmentMatcher)在 apollo 配置中,你必须使用外部文件定义你的 clientOptions

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

export default (context) => {
  return {
    httpEndpoint: 'http://localhost: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 example

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

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

errorHandler example

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

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

Options

你可以(在一个简单的设置)只需添加一个对象,如上所述。 如果您需要覆盖缓存或默认的 getAuth() 函数,则使用返回客户端配置选项的配置文件的路径。

clientConfigs Option: required

设置 apollo 客户端端点。 您可以在此处<找到每个端点的所有可用选项/a>

查看 官方 vue-apollo-cli,其中提供了可能的用例。

clientConfigs.default Object: required

clientConfigs.Object|Path: optional

tokenName String: optional, default: 'apollo-token'

将在身份验证时设置的 cookie 的令牌名称。 您还可以在每个 clientConfigs 中提供一个选项 tokenName 以覆盖默认值。 当发出每个请求时,此 cooke 中的任何值都将按照下面的 authenticationType 指定的“授权”HTTP 标头发送。

authenticationType String: optional, default: 'Bearer'

为任何授权请求设置身份验证类型。 如果您的 GraphQL API 需要的身份验证类型不是默认的 Bearer,请修改此项。 然后,所有请求都将使用以下格式的适当 HTTP 标头发送:“授权:"(例如 授权:承载 abc123)。

如果您的后端需要格式为“Authorization:”且没有任何前缀的授权标头,那么您应该将此值设置为空字符串。

includeNodeModules Boolean: optional, default: false

在如果您在 node_module 文件夹中使用 *.gql 文件,您可以启用 graphql-tag/loader 来为您解析文件。

Authentication

您有以下可用的身份验证方法:

 // 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' */)

查看完整示例

User login

// ~/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)
      }
    },
  }
}

User logout

// ~/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'
    })
  }
}

Examples to access the defaultClient of your apolloProvider

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

export default {
  actions: {
    foo (store, payload) {
      let client = this.app.apolloProvider.defaultClient
    }
  }
}
asyncData/fetch method of page component
// ~/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
  }
}
access client or call mutations and queries of any method inside of component
// ~/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 参考

Smart queries on any component

// nuxt.config.js

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

请参阅 vue-apollo 文档 了解有关智能查询的更多信息

Add GQL file recognition on node_modules

// nuxt.config.js

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

Upgrade

Upgrade Guide apollo-module v3 => v4

此模块的版本 4 为您提供零配置。 这意味着我们使用 vue-cli-plugin-apollo 中可用的最佳方法和相同的配置行为。 这意味着您不需要连接自己的配置,只需

按以下方式编辑您的配置:

// nuxt.config.js

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

Upgrade Guide apollo-client v1 => v2

此模块的版本 3 使用 apollo-client 2.x。 您需要确保根据 apollo-client 的升级指南更新所有中间件/后件。 检查此来源以获取参考:https:

Troubleshooting

Proxies

//www.apollographql.com/docs/apollo-server/migration-two-dot/ CORS 错误最常通过代理解决。 如果您在客户端控制台中看到跨源请求错误,请考虑设置代理。 查看 https://github.com/nuxt-community/proxy-module 以进行快速直接的设置。

ctx.req.session - req is undefined

这只是一个占位符。 您需要将其替换为您选择存储令牌的任何存储机制。 这是一个使用本地存储的示例:https://github.com/Akryum/vue-apollo/issues/144

Contribute and wire up setup

.env 根文件夹中的文件中设置必填字段 在 <

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

code>index.vue 中 登录过程需要 gql 端点启用一个返回有效令牌的突变:

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

如果你的 gql 后端准备好开始运行 nuxt,如下所示

npm install
npm run dev

Apollo inside of NuxtJS

npm versionlicense

Warning

This version requires Vue 2.6+ with serverPrefetch support. For example:

npm install --save vue@2.6.6 vue-template-compiler@2.6.6 vue-server-renderer@2.6.6

Sometime you may need to remove/rebuild package-lock.json/yarn.lock to make it work.

Setup

1- Install apollo module

npm install --save @nuxtjs/apollo

or

yarn add @nuxtjs/apollo

2- Load @nuxtjs/apollo module

// nuxt.config.js

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

  apollo: {
    clientConfigs: {
      default: {
        httpEndpoint: 'http://localhost:4000',
      }
    }
  }
}

3- Loading *.gql or *.graphql files (optional)

Install graphql-tag

npm install --save graphql-tag

or

yarn add graphql-tag

:warning: Typescript users

Add a gql.d.ts file in your sources folder with the following content:

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
}

Usage

You have a successfully enabled vue-apollo in your project.

Checkout Official example and vue-apollo official documentation for how to use vue-apollo inside your application

Advanced configuration

{
  // 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: 'http://localhost: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://localhost: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 using file configuration

:warning: In case you need to declare functions (like getAuth or inMemoryCacheOptions.fragmentMatcher) inside apollo configuration, you MUST define your clientOptions using an external file

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

export default (context) => {
  return {
    httpEndpoint: 'http://localhost: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 example

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

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

errorHandler example

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

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

Options

You can either (in a simple setup) just add an object as described above. If you need to overwrite cache or the default getAuth() function then use a path to your config file which returns the client config options.

clientConfigs Option: required

Sets up the apollo client endpoints. All available options for each endpoint you find here

Check out official vue-apollo-cli where possible usecases are presented.

clientConfigs.default Object: required

clientConfigs.Object|Path: optional

tokenName String: optional, default: 'apollo-token'

Token name for the cookie which will be set in case of authentication. You can also provide an option tokenName in each of your clientConfigs to overwrite the default. When each request is made, the value of whatever is in this cooke will be sent in an "Authorization" HTTP header as specified by authenticationType below.

authenticationType String: optional, default: 'Bearer'

Sets the authentication type for any authorized request. Modify this if the authentication type your GraphQL API requires is not the default Bearer. All requests will then be sent with the appropriate HTTP header in the format: "Authorization:" (Eg. Authorization: Bearer abc123).

If your backend requires an Authorization header in the format "Authorization:", without any prefix, then you should set this value to an empty string.

includeNodeModules Boolean: optional, default: false

In case you use *.gql files inside of node_module folder you can enable the graphql-tag/loader to parse the files for you.

Authentication

You have following methods for authentication available:

 // 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' */)

Check out the full example

User login

// ~/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)
      }
    },
  }
}

User logout

// ~/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'
    })
  }
}

Examples to access the defaultClient of your apolloProvider

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

export default {
  actions: {
    foo (store, payload) {
      let client = this.app.apolloProvider.defaultClient
    }
  }
}
asyncData/fetch method of page component
// ~/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
  }
}
access client or call mutations and queries of any method inside of component
// ~/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
        })
    }
  }
}

Once you get the client, you can access its methods and properties. See API Reference

Smart queries on any component

// nuxt.config.js

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

See vue-apollo documentation for more information on smart queries

Add GQL file recognition on node_modules

// nuxt.config.js

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

Upgrade

Upgrade Guide apollo-module v3 => v4

Version 4 of this module leaves you with zero configuration. This means we use the best possible approach available from vue-cli-plugin-apollo and the same configuration behaviour. This means you don't need to wire up your own configuration, simply pass

Edit your configuration as following:

// nuxt.config.js

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

Upgrade Guide apollo-client v1 => v2

Version 3 of this module is using apollo-client 2.x. You need to make sure to update all your middle/afterware according to the upgrade guide of apollo-client. Check this source for a reference: https://www.apollographql.com/docs/apollo-server/migration-two-dot/

Troubleshooting

Proxies

CORS errors are most often resolved with proxies. If you see a Cross-Origin-Request error in your client side console look into setting up a proxy. Check out https://github.com/nuxt-community/proxy-module for quick and straight forward setup.

ctx.req.session - req is undefined

This is just a placeholder. You'll want to replace it with whatever storage mechanism you choose to store your token. Here is an example using local storage : https://github.com/Akryum/vue-apollo/issues/144

Contribute and wire up setup

Setup the required fields in .env file in root folder

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

In index.vue the login process requires that the gql endpoint enables a mutation which returns a valid token:

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

If your gql backend is prepared start running nuxt as follow

npm install
npm run dev
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文