Skip to content
← Todas las preguntas
Principiante

¿Por qué mutar props directamente genera warnings?

ComponentesErrores comunes

Porque Vue impone el flujo de datos unidireccional: las props van hacia abajo (padre a hijo), los eventos van hacia arriba (hijo a padre). Si un hijo modifica una prop directamente, el padre no se entera, y la próxima vez que el padre se re-renderice, sobreescribirá el cambio del hijo.

vue
<script setup lang="ts">
const props = defineProps<{ count: number }>()

function increment() {
  props.count++ // ⚠️ Warning: Attempting to mutate prop "count"
}
</script>

Vue muestra este warning porque casi siempre es un bug. El propietario de los datos (padre) y quien los muta (hijo) están desincronizados.

Cómo solucionarlo

Opción 1: Emitir un evento y dejar que el padre gestione el cambio.

vue
<!-- Hijo -->
<script setup lang="ts">
const props = defineProps<{ count: number }>()
const emit = defineEmits<{ update: [value: number] }>()

function increment() {
  emit('update', props.count + 1)
}
</script>

<!-- Padre -->
<Counter :count="count" @update="count = $event" />

Opción 2: Usar v-model (atajo para el patrón anterior).

vue
<!-- Hijo -->
<script setup lang="ts">
const count = defineModel<number>()
</script>

<template>
  <button @click="count++">{{ count }}</button>
</template>

<!-- Padre -->
<Counter v-model="count" />

Opción 3: Usar una copia local si la prop es solo un valor inicial.

ts
const props = defineProps<{ initialCount: number }>()
const count = ref(props.initialCount)

Llama a la prop initialX para indicar que solo se usa una vez y no se mantendrá sincronizada con el padre.

Publicado bajo la licencia MIT.