Comunicación entre Componentes
Binding Bidireccional entre Componentes
El binding bidireccional entre componentes mantiene sincronizado un valor entre un componente padre y uno hijo, permitiendo que ambos participen en su actualización.
Ejemplo
Actualizar la cantidad de artículos de un carrito desde un selector reutilizable.
VuedefineModel + v-model
<script setup lang="ts">
import { ref } from 'vue'
import QuantitySelector from './QuantitySelector.vue'
const quantity = ref(1)
</script>
<template>
<p>Items in cart: {{ quantity }}</p>
<QuantitySelector v-model="quantity" />
</template>
// QuantitySelector.vue
<script setup lang="ts">
const quantity = defineModel<number>({ required: true })
function increment() {
quantity.value += 1
}
</script>
<template>
<button @click="increment">Add one</button>
</template>
El hijo declara defineModel(), que crea una prop de modelo que puede actualizar. El padre la enlaza con v-model.
Reactvalue + onChange
import { useState } from 'react'
import { QuantitySelector } from './QuantitySelector'
function App() {
const [quantity, setQuantity] = useState(1)
return (
<>
<p>Items in cart: {quantity}</p>
<QuantitySelector value={quantity} onChange={setQuantity} />
</>
)
}
// QuantitySelector.tsx
type QuantitySelectorProps = {
value: number
onChange: (value: number) => void
}
export function QuantitySelector({
value,
onChange,
}: QuantitySelectorProps) {
return (
<button onClick={() => onChange(value + 1)}>Add one</button>
)
}
El padre mantiene el estado y pasa el valor junto con una función para que el hijo solicite cambios.
Angularmodel() + [(...)]
import { Component, signal } from '@angular/core'
import { QuantitySelectorComponent } from './quantity-selector.component'
@Component({
selector: 'app-root',
standalone: true,
imports: [QuantitySelectorComponent],
template: `
<p>Items in cart: {{ quantity() }}</p>
<app-quantity-selector [(quantity)]="quantity" />
`,
})
export class AppComponent {
quantity = signal(1)
}
// quantity-selector.component.ts
import { Component, model } from '@angular/core'
@Component({
selector: 'app-quantity-selector',
standalone: true,
template: `
<button (click)="increment()">Add one</button>
`,
})
export class QuantitySelectorComponent {
quantity = model.required<number>()
increment() {
this.quantity.update((value) => value + 1)
}
}
El hijo declara model() y el padre crea un binding bidireccional con [(quantity)].
