UniAPP 中使用 GraphQL 支持的问题记录及解决方案

本教程基于 UniAPP (Vite/Vue3)open in new window 来添加 GraphQL 支持

初始化项目

npx degit dcloudio/uni-preset-vue#vite my-vue3-project

以下正题

一、安装Villus(GraphQL客户端)

Villusopen in new window 是vue.js的一个小而快速的graphql客户端,支持Vue3 及Composition API。

  1. 添加villus包
pnpm add villus graphql
or
npm add villus graphql
or
yarn add villus graphql
  1. 安装到Vue项目
  • 创建Villus插件包(这里示例命名为gql.ts)

src/plugins/gql.ts

import { getToken } from '~/utils/token'
import { createClient, fetch } from 'villus'

type Methods = 'OPTIONS' | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT'

// 此处重写fetch,请求采用UniAPP提供的uni.request
const fetchPlugin = fetch({
  fetch(url, options) {
    let token = getToken()
    return new Promise((resolve, reject) => {
      uni.request({
        url: url.toString(),
        method: options?.method as Methods,
        data: options?.body as any,
        header: {
          ...options?.headers,
          ...(token ? { Authorization: `Bearer ${token}` } : {}),
        },
        success(res) {
          return resolve({
            ok: true,
            status: res.statusCode,
            headers: res.header,
            text: async () => JSON.stringify(res.data),
            json: async () => res.data,
          } as Response)
        },
        fail(e) {
          return reject(e)
        },
      })
    })
  },
})

export const apolloClient = createClient({
  url: 'http://localhost:4001/graphql',
  use: [fetchPlugin],
})
  • 引用创建的gql包

引入gql插件因为UniAPP中使用SSR模式,故支持CompositionAPI注入模式会无法找到初始Client,所以推荐使用Vue插件方式open in new window安装

main.ts

import { apolloClient } from './plugins/gql'

export function createApp() {
  const app = createSSRApp(App)

  app.use(apolloClient)
  return {
    app,
  }
}

使用Villus请求

  1. 在vue文件中使用
    <div v-if="isFetching">Loading...</div>
      <div v-else-if="error">
        oh no ...{{ error }}
      </div>
      <div v-else>
        {{ data }}
      </div>
    </div>
    
    <script lang="ts" setup>
    import { useQuery } from 'villus'
    
    const { data, isFetching, error } = useQuery({
      query: FindManyActorDocument,
    })
    </script>
    

添加Villus插件等工具

参考官方介绍页open in new window可以使用 fetch(我们用来覆盖请求方法), cacheopen in new window, dedupopen in new window等等库,

参考