Props reactivos con toRefs en Vue.js

Resumen

Trabajar con props en Composition API te permite recibir datos desde un componente padre y mantener la reactividad dentro de la función setup. Aquí aprendes cómo declararlos, leerlos y conservar su reactividad usando toRefs, una pieza clave para quienes ya conocen Options API y quieren migrar a la sintaxis moderna de Vue.js.

¿Cómo declarar props en un componente con Composition API?

La declaración de props no cambia respecto a Options API: sigue siendo una option que defines al mismo nivel que setup. Lo que cambia es la forma en que accedes a esos valores dentro del componente.

Para declarar un prop puedes definir su tipo directamente o usar un objeto con propiedades adicionales. Algunas opciones útiles que puedes configurar son:

  • El tipo de dato, por ejemplo String, Number o Boolean.
  • Un valor por defecto cuando el padre no envía nada.
  • La propiedad required en true o false para forzar el envío del prop.

js props: { firstName: String, lastName: String }

Desde el componente padre puedes pasar los atributos usando kebab-case, por ejemplo first-name="Diana" y last-name="Martínez". Vue.js interpreta automáticamente esa sintaxis y la convierte a camelCase dentro del componente hijo [02:15].

¿Por qué puedo escribir first-name y leerlo como firstName? Vue.js traduce automáticamente entre kebab-case en el template y camelCase en el código JavaScript, así que ambas formas funcionan sin configuración extra.

¿Cómo leer los props dentro de la función setup?

La función setup recibe dos argumentos: el primero es props y el segundo es context. El objeto props es un JSON que contiene los valores enviados desde el padre, así que el acceso parece tan simple como desestructurar:

js setup(props) { const { firstName, lastName } = props }

Y aquí viene lo interesante: si lo haces así, Vue.js te lanza una advertencia. La consola te dirá que obtener el valor de props directamente puede causar que se pierda la reactividad [03:40]. Esto sucede porque al desestructurar un objeto plano, las variables resultantes quedan desconectadas del sistema reactivo de Vue.js.

En la práctica, esto significa que si el componente padre cambia el valor de firstName durante la ejecución, tu componente hijo no detectará el cambio y la vista no se actualizará.

¿Cómo mantener la reactividad de los props con toRefs?

Para resolver el problema de reactividad, Vue.js ofrece la función toRefs. Esta función recibe un objeto plano y lo convierte en un objeto de referencias reactivas, donde cada propiedad pasa a ser un ref individual que mantiene la conexión con el estado original.

js import { toRefs } from 'vue'

setup(props) { const { firstName, lastName } = toRefs(props) return { firstName, lastName } }

Con esto, cualquier cambio que ocurra en el componente padre se propaga al hijo sin perder reactividad. Si pruebas cambiar el atributo de Diana Martínez a Miguel Torres desde el padre, el hijo refleja el nuevo valor de inmediato [05:20].

¿Cuándo debo usar toRefs en lugar de acceder a props directamente? Úsalo siempre que necesites desestructurar props para trabajar con propiedades individuales y conservar reactividad. Si solo lees props.firstName sin desestructurar, la reactividad se mantiene de forma natural.

¿Puedo combinar props con computed y watchers?

Sí, y esa es una de las grandes ventajas del Composition API. Puedes combinar propiedades computadas, watchers y referencias reactivas de props en el mismo bloque setup. Por ejemplo, podrías crear un computed que concatene firstName y lastName para mostrar el nombre completo, o un watcher que reaccione al cambio de un prop específico.

Algunas combinaciones útiles que puedes explorar:

  • Un computed que dependa de varios props para generar texto derivado.
  • Un watch sobre un prop reactivo para disparar efectos secundarios.
  • Acceso a .value cuando trabajas con refs dentro de funciones computadas.

Todas las características que has visto en Vue.js siguen siendo combinables entre ellas, así que tienes libertad total para diseñar la lógica de tus componentes según el caso. Cuéntame en los comentarios qué experimentos has hecho combinando props reactivos con otras funciones del Composition API.