Skip to content

Qué es Vue y comparación con React ​

Antes de escribir código, conviene entender qué es Vue, qué problema resuelve y en qué se diferencia de React. Así podrás decidir con criterio qué herramienta usar en cada proyecto (y explicárselo a un cliente).

Concepto ​

El problema que resuelve ​

Con JavaScript puro, mantener la pantalla sincronizada con los datos se vuelve difícil: cada vez que algo cambia, tienes que buscar elementos con querySelector y actualizarlos a mano. En una app grande es fácil olvidar algún lugar y que la interfaz quede inconsistente.

Vue propone un modelo declarativo y reactivo:

  1. Declaras tus datos.
  2. Escribes una plantilla HTML que usa esos datos.
  3. Cuando los datos cambian, Vue actualiza automáticamente las partes de la página que dependen de ellos.

Analogía: es como una hoja de cálculo. Si la celda C1 es =A1+B1 y cambias A1, C1 se actualiza sola. En Vue, si cambias un dato, todo lo que lo usa en la pantalla se actualiza solo.

Un primer vistazo ​

Guarda esto como index.html y ábrelo en el navegador (es sólo para experimentar; en la siguiente lección crearás un proyecto real):

html
<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <title>Mi primer Vue</title>
</head>
<body>
  <div id="app">
    <h1>Hola, {{ nombre || 'mundo' }} 👋</h1>
    <input v-model="nombre" placeholder="Escribe tu nombre">
    <button @click="clics++">Clics: {{ clics }}</button>
    <p v-if="clics >= 5">¡Ya van {{ clics }} clics!</p>
  </div>

  <script type="module">
    import { createApp, ref } from 'https://unpkg.com/vue@3.5.13/dist/vue.esm-browser.js'

    createApp({
      setup() {
        const nombre = ref('')
        const clics = ref(0)
        return { nombre, clics }
      }
    }).mount('#app')
  </script>
</body>
</html>

Escribe en el input y el saludo cambia al instante; haz clic y el contador sube. Nunca tocaste el DOM directamente.

Ideas clave de Vue ​

  • Plantillas HTML: escribes HTML válido extendido con directivas (v-if, v-for, v-model). Muy fácil para quien viene de HTML/CSS.
  • Reactividad automática: Vue rastrea qué datos usa cada parte de la plantilla y sólo actualiza lo necesario.
  • Single File Components (.vue): plantilla, lógica y estilos de un componente en un solo archivo.
  • Progresivo: puedes usar sólo la librería en una página o el ecosistema completo (Router, Pinia, Nuxt).
  • Ecosistema oficial: Vue Router, Pinia, Vite (creado por el mismo autor de Vue) y Nuxt están coordinados con el núcleo.

Options API vs Composition API ​

Vue tiene dos estilos para escribir componentes. Verás ambos en proyectos existentes:

vue
<script setup>
import { ref, computed } from 'vue'

const precio = ref(100)
const cantidad = ref(2)
const total = computed(() => precio.value * cantidad.value)

function agregar() {
  cantidad.value++
}
</script>

<template>
  <p>{{ cantidad }} × ${{ precio }} = ${{ total }}</p>
  <button @click="agregar">Agregar</button>
</template>
vue
<script>
export default {
  data() {
    return { precio: 100, cantidad: 2 }
  },
  computed: {
    total() {
      return this.precio * this.cantidad
    }
  },
  methods: {
    agregar() {
      this.cantidad++
    }
  }
}
</script>

<template>
  <p>{{ cantidad }} × ${{ precio }} = ${{ total }}</p>
  <button @click="agregar">Agregar</button>
</template>

En este curso usamos Composition API con <script setup>: es más concisa, se lleva mejor con TypeScript y permite reutilizar lógica con composables. Si heredas un proyecto con Options API, los conceptos (datos reactivos, computadas, métodos) son los mismos.

Vue vs React ​

Ambos son excelentes y comparten ideas: componentes, estado reactivo, Virtual DOM, flujo de datos de padres a hijos. Las diferencias están en el estilo y la filosofía.

VueReact
TipoFramework progresivoLibrería de UI
PlantillasHTML con directivas (v-if, v-for)JSX (JavaScript con sintaxis tipo HTML)
ReactividadAutomática: modificas el dato (contador.value++)Explícita: llamas a setContador(...) e inmutabilidad
RendersVue sabe exactamente qué cambióVuelve a ejecutar el componente; optimizas con memo o el Compiler
Estilos<style scoped> integradoCSS Modules, Tailwind, CSS-in-JS (eliges tú)
Formulariosv-model (enlace bidireccional)value + onChange
Rutas y estadoOficiales: Vue Router, PiniaDe la comunidad: React Router, Zustand, TanStack
Meta-frameworkNuxtNext.js
Curva de aprendizajeSuaveMedia
Mercado laboralGrande (fuerte en Asia, Europa y agencias)El más grande

El mismo componente en ambos ​

vue
<script setup>
import { ref } from 'vue'

const tareas = ref(['Diseñar logo', 'Enviar cotización'])
const nueva = ref('')

function agregar() {
  if (!nueva.value.trim()) return
  tareas.value.push(nueva.value.trim()) // mutación directa: Vue lo detecta
  nueva.value = ''
}
</script>

<template>
  <input v-model="nueva" @keyup.enter="agregar" placeholder="Nueva tarea">
  <ul>
    <li v-for="t in tareas" :key="t">{{ t }}</li>
  </ul>
  <p v-if="tareas.length === 0">Sin tareas</p>
</template>
jsx
import { useState } from 'react'

export default function Tareas() {
  const [tareas, setTareas] = useState(['Diseñar logo', 'Enviar cotización'])
  const [nueva, setNueva] = useState('')

  function agregar() {
    if (!nueva.trim()) return
    setTareas([...tareas, nueva.trim()]) // copia nueva: inmutabilidad
    setNueva('')
  }

  return (
    <>
      <input
        value={nueva}
        onChange={(e) => setNueva(e.target.value)}
        onKeyUp={(e) => e.key === 'Enter' && agregar()}
        placeholder="Nueva tarea"
      />
      <ul>
        {tareas.map((t) => <li key={t}>{t}</li>)}
      </ul>
      {tareas.length === 0 && <p>Sin tareas</p>}
    </>
  )
}

¿Cuál elegir? ​

Elige Vue si...Elige React si...
Vienes de HTML/CSS y quieres resultados rápidosBuscas el mercado laboral más amplio
Trabajas con Laravel o en una agencia que ya usa VueEl equipo ya usa React o Next.js
Prefieres herramientas oficiales coordinadasQuieres el ecosistema más grande de librerías
Necesitas agregar interactividad a páginas existentesPlaneas hacer apps móviles con React Native

La buena noticia: los conceptos se transfieren. Si aprendes uno, el otro te costará la mitad.

Buena práctica

No elijas framework por moda: elige por el proyecto, el equipo y lo que el cliente podrá mantener. Para un cliente con un sitio en Laravel, Vue suele ser la opción más natural.

Error común

Usar el build de Vue desde un CDN (como en el ejemplo de arriba) para un proyecto real. Es útil para experimentar o para agregar algo pequeño a una página existente, pero para una app usa Vite: obtienes componentes .vue, recarga instantánea y un build optimizado.

Ejercicios ​

  1. Modifica el ejemplo HTML para agregar un botón "Reiniciar" que ponga el contador en 0 y que sólo aparezca cuando el contador sea mayor que 0.
  2. Agrega al ejemplo una lista de frutas (arreglo) que se muestre con v-for y un input para agregar nuevas al presionar Enter.
Ver solución
html
<div id="app">
  <h1>Hola, {{ nombre || 'mundo' }} 👋</h1>
  <input v-model="nombre" placeholder="Escribe tu nombre">

  <!-- 1 -->
  <button @click="clics++">Clics: {{ clics }}</button>
  <button v-if="clics > 0" @click="clics = 0">Reiniciar</button>

  <!-- 2 -->
  <input v-model="fruta" @keyup.enter="agregarFruta" placeholder="Nueva fruta">
  <ul>
    <li v-for="f in frutas" :key="f">{{ f }}</li>
  </ul>
</div>

<script type="module">
  import { createApp, ref } from 'https://unpkg.com/vue@3.5.13/dist/vue.esm-browser.js'

  createApp({
    setup() {
      const nombre = ref('')
      const clics = ref(0)
      const fruta = ref('')
      const frutas = ref(['Mango', 'Manzana'])

      function agregarFruta() {
        if (!fruta.value.trim()) return
        frutas.value.push(fruta.value.trim())
        fruta.value = ''
      }

      return { nombre, clics, fruta, frutas, agregarFruta }
    }
  }).mount('#app')
</script>

Resumen ​

  • Vue es un framework progresivo, declarativo y reactivo: cambias los datos y la pantalla se actualiza sola.
  • Usa plantillas HTML con directivas y Single File Components (.vue).
  • La Composition API con <script setup> es el estilo moderno recomendado.
  • Frente a React: plantillas en vez de JSX, reactividad automática en vez de setState, herramientas oficiales para rutas y estado.

Academia Web — aprende, copia y construye.