以前的项目一直采用 Uniapp + Vue2 结合 GraphQL 进行开发。然而,在升级到 Vue3 项目之后,发现市面上缺乏能够轻松兼容 Uniapp 的 GraphQL 解决方案。在这篇文章中,我将分享在 Vue3 和 Uniapp 环境中使用 GraphQL 的一些经验。
下面是我的github 仓库
也可以单独安装
使用了 Villus villus.logaretm.com/
环境要求在 node >= 14
npm i graphql villus
src路径下添加 graphql\gql.ts 文件
import { getToken } from '@/utils/cookie'
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) {
const 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) {
console.log(`res.data ====>`, res.data)
return resolve({
ok: true,
status: res.statusCode,
headers: res.header,
text: async () => JSON.stringify(res.data),
json: async () => res.data,
} as Response)
},
fail(e) {
console.log(`e ====>`, e)
return reject(e)
},
})
})
},
})
export const apolloClient = createClient({
use: [fetchPlugin],
url: 'https://----------/graphql-api/graphql', // 你的基地址
})
main.ts 文件下 导入graphql
import { apolloClient } from './graphql/gql'
export function createApp() {
const app = createSSRApp(App)
app.use(apolloClient)
return {
app,
}
}
使用 graphql 添加graphql/api.ts 文件
import { useQuery } from 'villus'
const textApi = () => {
return useQuery({
query: `query TheQuery($skip: Int, $take: Int, $name: String) {
data: m_list(
skip: $skip
take: $take
where: {
name: {
contains: $name
}
}){
items {
id
name
}
totalCount
}}`,
})
}
export { textApi }
页面使用
import { textApi } from '@/graphql/api/text' 导入,根据项目存放的位置自行调整
<template>
<div v-if="isFetching">Loading...</div>
<div v-else-if="error">oh no ...{{ error }}</div>
<div v-else>
{{ data }}
</div>
</template>
<script lang="ts" setup name="index">
import { textApi } from '@/graphql/api/text'
const { data, onData, error, isFetching } = textApi()
onData((data) => {
console.log('data', data)
})
</script>