Прежде чем описать проблему и вопрос, основанный на этой проблеме, я должен сказать, что это в первую очередь архитектурная проблема, и я много раз искал ответ или что-то подобное с разными ключевыми словами, но всегда получал руководства и статьи. как «Ваше первое приложение GraphQL с Vue и Typescript». Похоже, у меня есть более сложный вопрос, который требует более сложного способа ответа, и я считаю, что, задавая его там, я могу получить по крайней мере первый минимальный ключ к ответу, который мне нужен.
Также я Очень извиняюсь, если я продублировал или задал вопрос, на который был дан ответ раньше. Basi c поиск через stackoverflow не дал мне никаких результатов.
Итак, допустим, у нас есть схема GraphQL, которая содержит следующие типы
type Company {
id: ID!
name: String!
code: String
address: Address
}
type Address {
id: ID!
city: String!
# here might be many other fields, but provided ones are enough to ask
}
У нас также есть запрос в схеме
type Query {
companies (input: FindCompaniesInput!): [Company!]!
}
И его оболочка внешнего интерфейса
query Company ($input: FindCompaniesInput!, $withAddress: Boolean, $withCode: Boolean) {
companies(input) {
...CompanyItem
code @include(if: $withCode)
address @include(if: $withAddress) {
id
city
}
}
}
И запрос тип ввода выглядит следующим образом
type FindCompaniesInput {
ids: [ID!]
take: Int
offset: Int
nameLike: String
cityLike: String
}
В 7 различных компонентах Vue мне нужно загрузить один из 4 фрагментов на основе типа Company
используя запрос companies
. Например, для выпадающего компонента ввода мне нужно это
fragment CompanyItem on Company {
id
name
}
, но для компонента карты компании мне нужно
fragment CompanyCard on Company {
id
name
address {
city
}
}
и т. Д.
Теперь о Vue приложение Я использую Vue с Typescript и соответствующими пакетами, такими как vue-class-component
и vue-property-decorator
. Для генерации типов из схемы я использую apollo-graphql
. Я разработал приложение, не сохраняя графические объекты в Vuex. Я использую миксины для этой цели. Я понимаю, что использование паттернов, основанных на миксинах, рискованно, но я минимизировал риски (или думаю, что сделал это), используя следующий подход
Я объявляю миксин контекстов
import { CompanyItem } from '@/api/graphql/generated/fragments'
type CompanyMixinContext = {
items: CompanyItem
isPageLoading: boolean
}
@Component
export class CompanyMixin extends Vue {
// I swap place of 'mixin' suffix in name, to easily access it in vue-dev-tools
// component properties are sorted, so all inherited mixins display grouped
protected mixinCompany: CompanyMixinContext = {
items: null
isPageLoading: false
}
protected async queryCompaniesPage(input: FindCompaniesInput) {
// ...here I query companies chunk and wrap it in try/catch/finally
}
}
И затем, когда это необходимо, я расширяю свой компонент с помощью mixin.
<script lang="ts">
// omit imports...
@Component
export default MyComponent extends CompanyItemMixin {
// To use mixin context in template I declare a getter,
// omitting in its name a 'mixin' suffix
private get company () { return this.mixinCompany }
// The rest code of the component...
}
</script>
Наконец, когда я показал код, который сейчас используется в моем приложении, я теперь могу задать вопрос .
Есть ли способ использовать одиночный запрос с параметрами для сущности, даже без миксинов, но с возможностью многократного использования кода vue + машинописного текста, который может возвращать правильный тип на основе переменных?
Надеюсь не хочу писать 7 функций, или, в моем случае, 7 миксинов, которые имеют 99% код идентификатора c и работают с той же сущностью GQL, но все еще различаются по типам, с которыми они работают.
ps Основная функция Использование GraphQL заключается в том, что вы можете запрашивать различные структуры сущностей по-разному, но как я могу уменьшить подобный код для обработки запросов и работы с ним, используя какой-то универсальный подход (vuex / mixins), для меня до сих пор остается загадкой. Я уверен, что есть много высококлассных внешних разработчиков, которые могут ответить на этот вопрос. Я начну здесь в поисках.
Заранее спасибо.