Todos los artículos

defineModel() en Vue 3.4+: La evolución elegante del v-model en componentes

A partir de Vue 3.4 y disponible en la actual versión 3.5+, defineModel() se ha convertido en una de las macros más potentes dentro del <script setup>. Esta nueva sintaxis te permite trabajar con v-model de forma más clara, concisa y tipada, eliminando la necesidad de declarar manualmente props y emits para la comunicación padre-hijo. Si estás trabajando con Vue 3.5+, ya deberías estar usándolo. ¿La clave? Menos boilerplate, más fluidez, y una integración impecable con los modifiers y múltiples v-model. ¡Dile adiós a modelValue verboso y hola a bindings con estilo!

LA

Luis Aldair Quispe Rios

2 min de lectura
defineModel() en Vue 3.4+: La evolución elegante del v-model en componentes

¿Qué es defineModel()?

Es una macro especial disponible únicamente en el contexto de <script setup>. Nos permite declarar una prop reactiva que está automáticamente conectada con el v-model del componente padre.

En resumen: menos código, menos errores, más claridad.

Ejemplo básico: Un input personalizado

<!-- CustomInput.vue -->
<script setup lang="ts">
const model = defineModel({ type: String })
</script>

<template>
  <input v-model="model" placeholder="Escribe algo..." />
</template>

Y lo usas así:

<!-- ParentComponent.vue -->
<script setup lang="ts">
const nombre = ref('')
</script>

<template>
  <CustomInput v-model="nombre" />
</template>

Automáticamente:

  • Se declara la prop modelValue

  • Se emite update:modelValue al cambiar

  • ¡No necesitas escribir props ni emits manualmente!

Múltiples v-models: ¿Y si quiero algo más que modelValue?

Fácil. Solo le das un nombre:

<!-- CounterComponent.vue -->
<script setup lang="ts">
const count = defineModel('count', { type: Number, default: 0 })

function incrementar() {
  count.value++
}
</script>

<template>
  <button @click="incrementar">Contador: {{ count }}</button>
</template>

En el padre:

<!-- ParentComponent.vue -->
<script setup lang="ts">
const clicks = ref(5)
</script>

<template>
  <Counter v-model:count="clicks" />
</template>

Cuidado con los valores por defecto

Un error común: declarar un valor por defecto en el hijo, pero no pasar nada desde el padre. Esto puede causar desincronización.

Consejo: si vas a usar default, asegúrate de manejar correctamente el valor inicial desde el padre, o usar una sincronización manual si es necesario.

¿Y los modificadores? .trim, .number, .lazy...

Sí, también funcionan. Se puede capturar y personalizar su comportamiento:

<script setup lang="ts">
const [texto, modifiers] = defineModel()

const [modelValue, modelModifiers] = defineModel({
  set(value) {
    if (modelModifiers.trim) {
      return value.trim()
    }
    return value
  }
})
</script>

Ahora en el padre:

<MyInput v-model.trim="mensaje" />

El set() se encarga de aplicar .trim antes de enviar el valor modificado al padre.

Conclusión

defineModel() es un game changer para quienes usamos <script setup> en Vue 3.4+. Hace que trabajar con v-model en componentes sea más natural, más limpio y menos propenso a errores. Es ideal tanto para componentes simples como para interfaces complejas con múltiples bindings.

Sigue leyendo

¿Cómo usar defineExpose?

¿Cómo usar defineExpose?

Dentro de un componente que utiliza <script setup>, defineExpose() es una macro del compilador que permite exponer de forma explícita variables, funciones o incluso refs para que puedan ser accesibles desde el exterior. Esto es útil, por ejemplo, cuando queremos controlar un componente a través de una referencia (ref) en el componente padre.
¿Cómo integrar Tailwind 4 en Vue.js 3 + Vite?

¿Cómo integrar Tailwind 4 en Vue.js 3 + Vite?

Tailwind CSS 4 ha llegado con una arquitectura optimizada para rendimiento y flexibilidad, ofreciendo compilaciones hasta 5 veces más rápidas y un flujo de trabajo más ágil. En este post, exploraremos cómo integrar esta nueva versión con Vue 3, aprovechando características como la detección automática de contenido, el nuevo motor de alto rendimiento, las variables CSS nativas y la compatibilidad con Vite. Si quieres construir interfaces modernas con menos configuración y más poder, acompáñame en esta guía donde aprenderás a instalar, configurar y usar Tailwind CSS 4 en Vue 3. 🚀
¿Y si Vue.js también hablara Web Components? La magia de defineCustomElement

¿Y si Vue.js también hablara Web Components? La magia de defineCustomElement

Si eres fan de Vue.js como yo, seguramente has creado componentes reutilizables una y otra vez. Pero… ¿alguna vez te preguntaste cómo compartir tus componentes Vue fuera de una app Vue? ¿Qué pasaría si pudieras usarlos en React, Angular o incluso en HTML puro? La respuesta está en los Web Components y Vue tiene una herramienta poderosa para eso: defineCustomElement. Hoy te voy a contar cómo Vue y los Web Components pueden ser mejores amigos. Te prometo que al final vas a querer probarlo en tu próximo proyecto (o experimento).