听过graphql吗?来看看vue中 是怎么实现graphql

3,274 阅读2分钟

上周和后端同事一起入门了graphql。嗯,发际线好像又后移了。。。。

今天我们就一起揭开graphql“神秘”的面纱吧!

具体的实现代码我已经放到github上了:github.com/huisunyang/…

graphql官网:graphql.cn/learn/

为什么要用graphql?

对比与最常用的rest,我们向后端发送请求的时候,后端返回的数据不一定都是我们需要的,通常返回的都会多一点。传输的数据数量也就多了。graphql就实现了前端根据ui自己去请求所需要的字段,不会造成多余的数据请求

具体参考:www.jianshu.com/p/f45fe96de…

前端如何实现

graphql的客户端使用最多的就是Apollo Client,当然vue也做了继承

vue-apollo的具体实现

安装依赖
npm install -S apollo-cache-inmemory apollo-client apollo-link apollo-link-context apollo-link-http vue-apollo
npm install --save graphql graphql-tag
创建apolloClient.js文件
import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloLink } from 'apollo-link'
// 与 API 的 HTTP 连接
const httpLink = createHttpLink({
  // 你需要在这里使用绝对路径 一定是以graphql结尾的路径
  uri: 'https:/xxxxxxxxxxxxxxxxxxxxxxxx/graphql'
})
// 中间件添加请求头
const middlewareLink = new ApolloLink((operation, forward) => {
  operation.setContext({
    headers: {
      'Application-Id': 'xxxxx'
    }
  })
  return forward(operation)
})
// 缓存实现
const cache = new InMemoryCache()
// 创建 apollo 客户端
const apolloClient = new ApolloClient({
  link: middlewareLink.concat(httpLink),
  cache
})
export default apolloClient
main.js中引入
import VueApollo from 'vue-apollo'
import ApolloClient from './network/apolloClient'
Vue.use(VueApollo)
const apolloProvider = new VueApollo({
  defaultClient: ApolloClient
})
Vue.config.productionTip = false

new Vue({
  router,
  apolloProvider,
  render: h => h(App)
}).$mount('#app')
页面中使用
 const getECards = gql`query ($page:Int,$pageSize:Int) {
        usedDetailStatistics (page:$page,pageSize:$pageSize) {
          data {
            orderId
          }
          totalPages
          totalElements
        }
        test
      }`
    this.$apollo.query({
      query: getECards,
      variables: {
        page: 0,
        pageSize: 20
      }
    }).then(res => {
      console.log('1233456', res)
    })

具体使用如上所述。下面介绍下我的踩坑之旅。。。

踩坑总结

1、后端接口method为get,前端的query请求提示请求方法错误?

这是因为前端发送的graphql请求无论是query还是mutation,都是post请求。

2、graphql请求浏览器的network显示type为fetch

这也就是graphql与rest的不同之处,rest请求type为xhr,即XMLHttpRequest,但是graphql却是fetch

关于fetch和ajax的不同请参考:juejin.cn/post/684490…

3、graphql接口前端是否可以通过rest的方式调用?

是可以的,graphql的官网提出是支持两种方式的

4、graphql的接口路径

切记,graphql的接口路径一定要以/graphql结尾!!!!这个坑了我们很久,官方文档也有说明,所以说好好看文档是多么重要!!!!

5、关于传参

动态传参一般分为三步:

gql`query ($page:Int,$pageSize:Int,$beginDate:LocalDate) { //1、声明查询接受的变量 变量前缀必须为$
        usedDetailStatistics (page:$page,pageSize:$pageSize,beginDate:$beginDate) {  //2、使用声明的变量替代查询中的静态值
          data {
            orderId
          }
          totalPages
          totalElements
        }
        test
      }`
this.$apollo.query({
      query: getECards,
      //3、将参数传递进去
      variables: {
        page: 0,
        pageSize: 20,
        beginDate: '2020-01-01'
      }
    }).then(res => {
      console.log('1233456', res)
    })

如果遇到后端自定义的参数类型,按照后端定义的类型名传递即可,如上面的LocalDate