[Meta] VueX presentational component patterns. Emit event VS. passing in event handler prop

Presentation vs. Container Component terminology

At the moment I don't think we make the distinction between 'presentation' component vs a 'container' component.

The fundamental difference, is that a 'presentation' component doesn't draw it's state directly from the VueX store, instead, it is derived from the props that are passed to it.

Presentational Components

Emitting Events vs. passing in a eventHandler function as a prop

We currently use both approaches in our code base, and emitting events feels like an anti-pattern.

Handler as a prop:

Parent Component:

<template>
      <div class="align-self-center">
        <chart-buttons 
          :days="days" 
          :active-day="vulnerabilitiesHistoryDayRange" 
          :click-handler="setVulnerabilitiesHistoryDayRange"
        />
      </div>
</template>

Child Component:

<template>
  <div class="btn-group">
    <gl-button
      v-for="day in days"
      :key="day"
      :class="{ active: activeDay === day }"
      variant="secondary"
      @click="clickHandler(day)"
      :data-days="day"
    >
      {{ buttonContent(day) }}
    </gl-button>
  </div>
</template>

VS.

Emitting events

Parent Component:

<template>
      <div class="align-self-center">
        <chart-buttons 
          :days="days" 
          :active-day="vulnerabilitiesHistoryDayRange" 
          @click="setVulnerabilitiesHistoryDayRange"
        />
      </div>
</template>

Presentational Component:


...
methods: {
 emitHandler(days){
  this.$emit('click',days);
 }
}
...

<template>
  <div class="btn-group">
    <gl-button
      v-for="day in days"
      :key="day"
      :class="{ active: activeDay === day }"
      variant="secondary"
      @click="emitHandler(day)"
      :data-days="day"
    >
      {{ buttonContent(day) }}
    </gl-button>
  </div>
</template>
Assignee Loading
Time tracking Loading