如何按需触发一次graphql useQuery?

Dar*_*te1 5 vue.js graphql vue-component apollo-client vue-composition-api

在graphql-codegenerator的帮助下,我们创建了一个useQuery能够正确从后端检索数据的graphql 。当在输入字段中输入字符串时,driverRule将调用该函数来验证输入,该函数又应该调用useQuery唯一一次。

问题

但是,当我们立即执行enable使用 useQuery 的查询时ref,会使用该方法调用第二次执行refetch()。所有后续调用driverRule将仅根据需要调用 useQuery 一次。但第一个调用会执行两次,这是不希望的。

import {computed, defineComponent, ref } from '@vue/composition-api'
import { useSapTruckRosterDriverQuery } from 'src/graphql/generated/operations'

export default defineComponent({
  setup(_, { emit }) {
    const showTruckId = ref(false)
    const driverId = computed(() => (!showTruckId.value ? answer.value : ''))
    const queryEnabled = ref<'driver' | 'truck'>()

    const { refetch: getDriverQuery } = useSapTruckRosterDriverQuery(
      () => ({ id: driverId.value }),
      () => ({ enabled: queryEnabled.value === 'driver' })
    )

    const driverRule = async (value: string) => {
      queryEnabled.value = 'driver'

      const result = await getDriverQuery({ id: value })

      if (result.data.driver.__typename === 'DriverArray') {
        return result.data.driver.data?.length ? true : 'Truck not found'
      }
    }
Run Code Online (Sandbox Code Playgroud)

我们尝试过的:

  • useQuery在函数内移动driverRule,但这会产生以下错误:

[Vue warn]:当没有要关联的活动组件实例时,会调用 onServerPrefetch。生命周期注入 API 只能在 setup() 执行期间使用。

  • useQuery 带有选项emabled: false并且仅refetch()driverRule. 这根本不执行 useQuery

解决方法

接受默认行为并默认使用静态变量值启用查询,并且不使用第一次运行的结果,而仅使用来自 的结果refetch()。虽然这仍然会导致对后端的两次调用,但这是无法避免的。

    const { refetch: getDriverQuery } = useSapTruckRosterDriverQuery(
      { id: 'initialQueryActivationCall' }
    )

    const driverRule = async (value: string) => {
      const result = await getDriverQuery({ id: value })
      if (result.data.driver.__typename === 'DriverArray') {
        return result.data.driver.data?.length ? true : 'Truck not found'
      }
    }
Run Code Online (Sandbox Code Playgroud)

问题

useQuery当函数driverRule被调用时只调用一次似乎真的很难。当后端只需要 1 次调用时,如何避免出现 2 次调用?

Jan*_*szO 2

您可以使用@vue/apollo-composable 包中的useApolloClient

//other imports...
import { useApolloClient } from '@vue/apollo-composable'
import { gql } from '@apollo/client/core'

export default defineComponent({
    setup() {
        const { client } = useApolloClient()

        const GET_DOGS = gql`
            query GetDogs {
                dogs {
                   id
                   breed
                }
            }
        `;

        const getDogs = async (): Promise<void> => {
            const { data, } = await client.query({
                query: GET_DOGS
            })
        }

        return {
            getDogs,
        }
    },
})
Run Code Online (Sandbox Code Playgroud)