RosettaJS: Comparativas de Vue, React y Angular

Component Communication

Child to Parent Communication

This pattern lets a child component notify the parent component when an action happens or when it needs to communicate a change.

Example

Notifying the parent component when a button inside the child is clicked.

VuedefineEmits

<script setup lang="ts">
import ChildButton from './ChildButton.vue'

function handleSave() {
  alert('Saved in parent')
}
</script>

<template>
  <ChildButton @save="handleSave" />
</template>
// ChildButton.vue
<script setup lang="ts">
const emit = defineEmits<{
  save: []
}>()
</script>

<template>
  <button @click="emit('save')">
    Save
  </button>
</template>

It uses defineEmits to declare child component events and send them to the parent when an action happens.

Reactcallback prop

function App() {
  function handleSave() {
    alert('Saved in parent')
  }

  return <ChildButton onSave={handleSave} />
}
// ChildButton.tsx
type ChildButtonProps = {
  onSave: () => void
}

function ChildButton({ onSave }: ChildButtonProps) {
  return (
    <button onClick={onSave}>
      Save
    </button>
  )
}

It receives a parent function as a prop and calls it from the child to communicate an action.

Angularoutput()

import { Component } from '@angular/core'
import { ChildButtonComponent } from './child-button.component'

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [ChildButtonComponent],
  template: `
    <app-child-button (save)="handleSave()" />
  `,
})
export class AppComponent {
  handleSave() {
    alert('Saved in parent')
  }
}
// child-button.component.ts
import { Component, output } from '@angular/core'

@Component({
  selector: 'app-child-button',
  standalone: true,
  template: `
    <button (click)="save.emit()">
      Save
    </button>
  `,
})
export class ChildButtonComponent {
  save = output<void>()
}

It uses output() to expose an event from the child so the parent can react from the template.