关于父子关系和组件的问题

Posted

技术标签:

【中文标题】关于父子关系和组件的问题【英文标题】:Question about parent/child relationships and components 【发布时间】:2019-10-30 21:11:20 【问题描述】:

我目前正在尝试将项目从 vuex/REST 移植到 vue-apollo。该项目显示了一个事件列表,每个事件都可以展开以显示详细信息,包括参与者。

所以我有一个EventList 组件,它获取列表所需的事件和所有属性。我有一个EventDetails 子组件,它从onclick 列表中展开。 EventDetails 需要一些事件数据以及要呈现的与会者列表。问题是,我找不到构建查询的优雅方法。

目前,我有一个事件查询,由EventList 组件执行:

query Events($type: [String!]) 
  events(type: $type) 
    id
    name
    attendeeCount
  

EventList 组件中,我将事件 ID 传递给 EventDetails 子组件,然后该子组件依次查询 API 以查找与会者:

query Event($id: ID!) 
  event(id: $id) 
    id
    name
    attendeeCount
    attendees 
      id
      name
      paymentState
    
  

父组件(简体):

<template>
  <EventDetails v-for="event in events" :eventId="event.id" />
</template>

<script lang="ts">
import …

@Component(
  apollo: 
    events:  … 
  ,
  components: 
    EventsDetails
  
)
export default class EventList extends Vue 
  events: Event[] = []

</script>

子组件(简体):

export default class EventDetails extends Vue 
  @Prop(Number) eventId!: ID
  // I'd like to pass in the complete event object here, and just
  // fetch another attribute "attendees" via graphql, like this:
  @Prop(Object) event!: Event

  apollo: 
    // Passing in the event as prop conflicts with this.
    // How can I fetch more attributes for a passed in object?
    // Is this even possible? Do I have to fetch everything again?
    // Is it possible with vue-apollo to just fetch the attendees
    // and return them as property "attendees" in the EventDetails
    // component?
    event: 
      query: gql`
        query Event($id: ID!) 
          event(id: $id) 
            ...event
            attendees 
              id
              aasmState
              event 
                id
                attendeeSelectionClosed
              
              ticket 
                id
                companyName
                position
              
            
          
        
        $eventFragment
      `,
      variables() 
        return  id: this.eventId 
      ,
      error(error) 
        console.log(error)
      
    
  

这种方法的问题是,对于名为 event 的查询,我无法将已经获取的事件作为道具传递,因此必须再次获取事件数据。此外,在展开EventDetails 面板(等待查询执行)后,无法立即呈现事件详情。

那么有没有办法通过 GraphQL 传入事件数据(不仅仅是 id)并仅查询与会者?我找到的唯一可能的解决方案是将另一个查询 attendees 添加到 GraphQL 服务器,我想避免这种情况,因为与会者总是分组在一个事件下,我们总是知道父事件对象。

但这在 GraphQL 领域被认为是好的架构吗?为您正在处理的每个对象类型添加一个查询类型,即使总是知道父对象并且通过父对象进行查询?

我很可能在这里尝试做一些愚蠢的事情,我对 GraphQL 架构还是很陌生。

非常感谢您的帮助。

【问题讨论】:

【参考方案1】:

那么有没有办法通过 GraphQL 传入事件数据(不仅仅是 id)并仅查询参加者?

不,在父查询中“询问”列表/详细信息视图中需要的部件(例如与会者姓名)。父查询的每个扩展 - 请求超集都会发出一个新请求,而不是使用已经获取的数据(从缓存中)。要求更早地保存请求。

我找到的唯一可能的解决方案是将另一个查询参与者添加到 GraphQL 服务器,我想避免这种情况,因为参与者总是分组在一个事件下,我们总是知道父事件对象。

在 react(我不使用 vue)中,您可以将数据作为 props 从父组件传递 - 无需将此数据混合到查询请求中

您可以使用attendees 上的简单过滤器“直接”(而不是通过event)请求attendees,f.e. attendees (eventID:'some id') ....——当然是由attendees解析器实现的

【讨论】:

嗨@xadm,感谢您的回复!不幸的是,我无法提前获取更多数据,因为数据太多。如果我这样做,事件列表视图将不再活泼。我认为直接邀请与会者是最好的方法。我想避免使用始终具有父对象的查询污染 GraphQL 查询空间,但也许这是最好的折衷方案。非常感谢! :) ?

以上是关于关于父子关系和组件的问题的主要内容,如果未能解决你的问题,请参考以下文章

vue.js学习笔记— 父子组件之间通信的第一种方式 props 和 $emit

如何将值从一个组件传递到另一个没有父子关系的库中的组件文件?

关于支付宝父子组件通信以及组件名定义的问题

如何使用物料清单的父子记录创建简单的数据关系

12.组件化开发2-非父子组件之间通信-祖先和后代之间的通信

Vue_(组件通讯)非父子关系组件通信