En esta página

¿Qué es Vue.js?

12 min lectura TextoCap. 1 — Fundamentos de Vue

¿Qué es Vue.js y por qué elegirlo?

Vue.js es un framework progresivo de JavaScript para construir interfaces de usuario. Fue creado por Evan You en 2014 y desde entonces ha crecido hasta convertirse en uno de los tres frameworks más populares del ecosistema web, junto a React y Angular.

La palabra clave es progresivo: Vue puede usarse tan poco o tanto como necesites. Puedes añadir Vue a una sola sección de una página HTML existente, o puedes construir una SPA (Single Page Application) completa con enrutamiento, gestión de estado y renderizado en servidor. Esta flexibilidad lo hace ideal tanto para proyectos pequeños como para aplicaciones de escala empresarial.

El sistema de reactividad de Vue

La característica más distintiva de Vue es su sistema de reactividad. Cuando creas datos reactivos con ref() o reactive(), Vue observa esos datos automáticamente. Cuando cambian, Vue actualiza el DOM de forma eficiente sin que tengas que hacer nada más.

Estado reactivo → DOM = f(estado)

Esto contrasta con la manipulación manual del DOM (jQuery, DOM APIs) donde el programador es responsable de sincronizar el estado con la vista. Con Vue, simplemente describes cómo debe verse la UI y el framework se encarga del resto.

Vue 3.5 — Las últimas novedades

La versión 3.5 de Vue, lanzada en septiembre de 2024, introdujo mejoras significativas que hacen el código más ergonómico:

Reactive Props Destructure

Antes de Vue 3.5, desestructurar props perdía la reactividad. Era necesario usar toRef(props, 'nombre') para mantenerla. Ahora, la desestructuración dentro de defineProps() es automáticamente reactiva:

<script setup lang="ts">
// Vue 3.5 — ¡esto ahora es reactivo!
const { nombre, edad = 18 } = defineProps<{
  nombre: string
  edad?: number
}>()
</script>

useTemplateRef()

useTemplateRef() es la nueva API para referenciar elementos del DOM. Es más explícita y mejor tipada que la API anterior con ref() como template ref:

import { useTemplateRef } from 'vue'

// El argumento debe coincidir con ref="nombre" en el template
const boton = useTemplateRef<HTMLButtonElement>('miBoton')

Composition API vs Options API

Vue ofrece dos estilos de escritura de componentes:

Options API (estilo Vue 2)

<script>
export default {
  data() {
    return { contador: 0 }
  },
  methods: {
    incrementar() { this.contador++ }
  },
  computed: {
    doble() { return this.contador * 2 }
  }
}
</script>

Composition API con script setup (Vue 3, recomendada)

<script setup lang="ts">
import { ref, computed } from 'vue'

const contador = ref(0)
const doble = computed(() => contador.value * 2)

function incrementar(): void {
  contador.value++
}
</script>

La Composition API tiene varias ventajas sobre Options API:

  • Reutilización de lógica: La lógica se extrae en funciones (composables) sin las limitaciones de mixins
  • Mejor TypeScript: Inferencia de tipos natural sin decoradores ni opciones de componente
  • Árbol de sacudido (tree-shaking): Solo importas lo que usas
  • Colocación de código: La lógica relacionada vive junta, no separada en data, methods, computed

El ecosistema Vue

Vue no es solo el framework core. Tiene un ecosistema oficial bien mantenido:

Vite

El servidor de desarrollo y bundler oficial para proyectos Vue. Ofrece inicio instantáneo, HMR (Hot Module Replacement) ultrarrápido y builds optimizados. Creado también por Evan You.

Vue Router

El enrutador oficial de Vue para SPA. Gestiona navegación, parámetros de ruta, guards de navegación y lazy loading de componentes.

Pinia

La solución de gestión de estado oficial (sucesor de Vuex). Ofrece stores tipadas, soporte de devtools, plugins y una API sencilla basada en Composition API.

Nuxt

El framework meta de Vue para aplicaciones con renderizado en servidor (SSR), generación estática (SSG) y rutas basadas en archivo. Es el equivalente de Next.js para React.

VueUse

Una colección de más de 200 composables utilitarios (similar a react-use). Incluye sensores, animaciones, almacenamiento, navegador y muchos más.

Crear un proyecto Vue con create-vue

La forma oficial de iniciar un proyecto Vue es con create-vue, basado en Vite:

# Con npm
npm create vue@latest

# Con Bun
bun create vue@latest

El asistente te preguntará si quieres TypeScript, JSX, Vue Router, Pinia, Vitest, ESLint y más. Para este curso seleccionaremos TypeScript, Vue Router y Pinia.

La estructura generada incluye:

mi-proyecto/
├── src/
│   ├── assets/          # Recursos estáticos
│   ├── components/      # Componentes reutilizables
│   ├── router/          # Configuración de Vue Router
│   ├── stores/          # Stores de Pinia
│   ├── views/           # Componentes de página/vista
│   ├── App.vue          # Componente raíz
│   └── main.ts          # Punto de entrada
├── public/
├── index.html
├── vite.config.ts
└── tsconfig.json

Vue en el mercado laboral

Vue es especialmente popular en:

  • Asia: Alibaba, Xiaomi, Baidu y muchas empresas asiáticas lo usan extensamente
  • Europa: Muchas startups y agencias digitales europeas lo prefieren por su curva de aprendizaje suave
  • Latinoamérica: Creciente adopción en empresas de tecnología regional

Si vienes de JavaScript puro o jQuery, Vue es generalmente considerado el framework más fácil para empezar. Si ya conoces React, encontrarás muchos conceptos familiares con una ergonomía diferente. Si vienes de Angular, apreciarás la similitud en conceptos como directivas y componentes, pero con menos boilerplate.

Por qué Vue 3.5 + TypeScript es la combinación ideal

Vue 3.5 fue construido desde cero con TypeScript en mente. La integración es tan profunda que:

  • Los props se tipan con genéricos: defineProps<{ titulo: string }>()
  • Los emits se tipan de forma declarativa: defineEmits<{ cambio: [valor: string] }>()
  • Los computed values infieren su tipo automáticamente
  • Los stores de Pinia son completamente tipados

Esto significa que obtienes autocompletado, detección de errores en tiempo de compilación y refactoring seguro, todo sin la verbosidad de anotar cada función manualmente.


Práctica

  1. Instala el entorno: Asegúrate de tener Node.js 20+ (o Bun) instalado. Ejecuta npm create vue@latest y selecciona TypeScript, Vue Router y Pinia.
  2. Explora la estructura: Abre el proyecto generado y familiarízate con los archivos. Ejecuta npm run dev y observa el HMR al modificar src/App.vue.
  3. Modifica tu primer componente: Cambia el contenido de HelloWorld.vue y observa la actualización en tiempo real. Añade una variable reactiva con ref() y muéstrala en el template.

En la siguiente lección aprenderemos a crear y estructurar Componentes de Archivo Único (SFC).

Vue 3.5 — novedades clave
Vue 3.5 introdujo Reactive Props Destructure (ya no necesitas toRef para props reactivas) y useTemplateRef() como reemplazo ergonómico de ref() para referencias a elementos del DOM. Ambas características son estables y recomendadas en proyectos nuevos.
Composition API vs Options API
Para proyectos nuevos siempre usa Composition API con script setup. Options API sigue soportada pero la comunidad y la documentación oficial han migrado completamente a Composition API. Las librerías más modernas como Pinia y VueUse están diseñadas pensando en ella.
Vue 3 no es compatible con Vue 2
Vue 3 introdujo cambios de ruptura respecto a Vue 2. Si encuentras tutoriales con Vue.component(), new Vue() o la Options API con this, es contenido de Vue 2. Asegúrate de estudiar documentación marcada explícitamente para Vue 3.
vue
<script setup lang="ts">
import { ref } from 'vue'

// ref() convierte un valor en reactivo
const mensaje = ref('¡Hola desde Vue 3.5!')
const contador = ref(0)

function incrementar(): void {
  contador.value++
}
</script>

<template>
  <div class="app">
    <h1>{{ mensaje }}</h1>
    <p>Contador: {{ contador }}</p>
    <button @click="incrementar">Incrementar</button>
  </div>
</template>

<style scoped>
.app {
  font-family: sans-serif;
  padding: 2rem;
}
</style>
vue
<script setup lang="ts">
// Vue 3.5 — Reactive Props Destructure
// Ya no necesitas toRef(props, 'titulo')
const { titulo, contador = 0 } = defineProps<{
  titulo: string
  contador?: number
}>()

// useTemplateRef — Vue 3.5
import { useTemplateRef, onMounted } from 'vue'
const inputRef = useTemplateRef<HTMLInputElement>('miInput')

onMounted(() => {
  inputRef.value?.focus()
})
</script>

<template>
  <div>
    <h2>{{ titulo }}</h2>
    <p>Contador: {{ contador }}</p>
    <input ref="miInput" type="text" placeholder="Foco automático" />
  </div>
</template>