#vue.js #graphql #vue-component #apollo-client #vue-composition-api
#vue.js #graphql #vue-компонент #apollo-клиент #vue-состав-api
Вопрос:
С помощью graphql-codegenerator мы создали graphql, useQuery
который корректно извлекает данные из серверной части. Когда строка вводится в поле ввода driverRule
, вызывается функция для проверки ввода, которая, в свою очередь, должна вызывать useQuery
только один раз.
Проблема
Однако, когда enable
мы ref
немедленно выполняем запрос с useQuery, с 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'
}
}
Что мы пробовали:
- Перемещение
useQuery
внутриdriverRule
функции, но это приводит к следующей ошибке:
[Vue warn]: onServerPrefetch вызывается, когда нет активного экземпляра компонента, с которым нужно связать. API-интерфейсы внедрения жизненного цикла могут использоваться только во время выполнения setup() .
- Используйте запрос с опцией
emabled: false
и толькоrefetch()
вdriverRule
. Это вообще не приводит к выполнению useQuery
Обходной путь
Примите поведение по умолчанию и включите запрос по умолчанию со значением статической переменной и используйте не результат первого запуска , а только результат из refetch()
. Это все равно приводит к 2 вызовам серверной части, но этого нельзя избежать.
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'
}
}
Вопрос
Кажется, действительно сложно просто вызвать useQuery
только один раз, когда driverRule
вызывается функция. Как мы можем избежать 2 вызовов, когда требуется только 1 вызов серверной части?
Комментарии:
1. Вы заглядывали в
useLazyQuery
? Это позволяет вам указывать, когда должен быть запущен запрос.
Ответ №1:
Вы можете использовать useApolloClient из @vue / apollo-composable пакета.
//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,
}
},
})