Tutorial VueJS 3 – Crear una aplicación Vue
verificado el 7 septiembre 2026 · 5 min
Crea el proyecto con npm create vue@latest, responde «no» a TypeScript y luego lanza npm install y npm run dev. Una aplicación Vue nace de createApp(App).mount('#app'), un dato declarado con ref() se muestra en la plantilla entre llaves dobles y se actualiza solo.
Una aplicación Vue es una instancia creada por createApp y enganchada a un elemento de la página. Este capítulo instala el proyecto y después muestra un primer dato en pantalla.
Crear el proyecto
Vue trae un generador oficial, create-vue, que monta un proyecto Vite configurado para Vue. Abre un terminal en la carpeta donde guardas tus proyectos:
npm create vue@latestEl generador hace una serie de preguntas. Para este tutorial, responde:
- Project name:
boutique-vue - TypeScript: No, nos quedamos en JavaScript para no mezclar dos aprendizajes.
- JSX, Vue Router, Pinia, ESLint, Prettier: No. Los añadiremos cuando hagan falta.
- Vitest: Sí si quieres escribir tests, si no No.
Muchos tutoriales indican npm create vue@latest -- --default para «ir rápido». En create-vue 3.23, ese flag activa TypeScript: acabas con un src/main.ts y ficheros tsconfig, que no es lo que buscas aquí. Mejor responde a las preguntas.
Instala las dependencias y arranca el servidor de desarrollo:
En Node 22, el npm incluido (10.9) se detiene con npm error Cannot read properties of null (reading 'edgesOut'), tanto en un proyecto nuevo como con el código de este tutorial. Actualice npm antes de instalar: npm install -g npm@latest. Node 24 no tiene este problema.
cd boutique-vue
npm install
npm run devVite muestra una dirección, normalmente http://localhost:5173/. Ábrela: aparece la página de inicio del proyecto.
Lo que ha creado el generador
boutique-vue/
├── index.html ← la seule vraie page HTML du site
├── package.json
├── vite.config.js
├── public/ ← fichiers servis tels quels
└── src/
├── main.js ← point d’entrée : crée et monte l’application
├── App.vue ← composant racine
├── assets/
└── components/Tres archivos cuentan por ahora. El generador también crea src/assets/main.css y base.css, el estilo de su página de inicio: podrá borrarlos, junto con la línea import './assets/main.css' que abre src/main.js, cuando el CSS del tutorial los sustituya al final del capítulo.
index.html contiene un contenedor vacío y carga el punto de entrada. Nada más: el resto de la página lo produce Vue.
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>src/main.js crea la aplicación a partir del componente raíz y la monta en ese contenedor.
import './assets/main.css'
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')createApp(App) construye la instancia, .mount('#app') le entrega el elemento del DOM que tiene derecho a gestionar. A partir de ahí, todo lo que está dentro de <div id="app"> pertenece a Vue.
El primer componente
Un fichero .vue es un componente monofichero: el script, la plantilla y el estilo de una misma parte de la interfaz viven en el mismo sitio. Vacía src/App.vue y escribe:
<script setup>
import { ref } from 'vue'
const product = ref('T-Shirt')
</script>
<template>
<div class="product-display">
<h1>{{ product }}</h1>
</div>
</template>Guarda: el navegador muestra «T-Shirt» sin recargar. Es el reemplazo de módulos en caliente de Vite.
Este fichero irá creciendo hasta el capítulo sobre los componentes, donde lo trocearemos.
Entender estas siete líneas
<script setup> le indica a Vue que ese bloque describe la lógica del componente. Todo lo que declares ahí en el primer nivel se puede usar en la plantilla, sin exportar nada.
ref('T-Shirt') crea una referencia reactiva: una caja que guarda un valor y avisa a Vue cuando cambia. En el script, la caja se abre con .value:
const product = ref('T-Shirt')
console.log(product.value) // 'T-Shirt'
product.value = 'Pull' // el título cambia inmediatamente en pantallaEn la plantilla, en cambio, se escribe {{ product }} sin .value: Vue desenvuelve la referencia automáticamente.
Las llaves dobles son una interpolación. Aceptan cualquier expresión JavaScript, no solo un nombre de variable:
<h1>{{ product }}</h1>
<h1>{{ product.toUpperCase() }}</h1>
<h1>{{ 'Notre ' + product }}</h1>La reactividad, en concreto
Cambia el valor inicial por 'Pull' y guarda: el título lo sigue. No has escrito ni una línea para buscar el h1 y cambiar su contenido. Ese es el núcleo de Vue: tú describes lo que la página debe mostrar en función del estado y Vue se encarga de la actualización.
El mismo componente se escribiría export default { data() { return { product: 'T-Shirt' } } }, y el script accedería con this.product. Con <script setup>, this no existe: solo hay variables.
¿Y las demás herramientas de build?
create-vue instala Vite, la herramienta que recomienda el equipo de Vue. Otros empaquetadores también compilan los ficheros .vue: Parcel mediante @parcel/transformer-vue, o webpack con vue-loader.
Funcionan, pero son más lentos y se salen del camino trillado. Medido el 2 de septiembre de 2026 sobre la misma aplicación de un solo componente:
Vite 8.2.2 build en 1,05 s → 60,57 kB (23,91 kB gzip)
Parcel 2.16.4 build en 10,57 s → 92,77 kBEl resultado de npm run build es una carpeta de ficheros estáticos. Lo que haya dentro decide tu posicionamiento, un tema que se trata aparte.
Quédate con Vite para un proyecto nuevo. Las alternativas solo se justifican si tu cadena de build actual ya depende de ellas.
El CSS del tutorial
Para que la aplicación tenga algo de aspecto, crea src/assets/boutique.css con las pocas reglas que se usan a lo largo de los capítulos:
.product-display { display: flex; gap: 32px; padding: 24px; font-family: system-ui, sans-serif; }
.product-image img { width: 240px; }
.variants-wrapper { display: flex; gap: 10px; }
.color-circle { width: 50px; height: 50px; margin-top: 8px; border: 2px solid #d8d8d8; border-radius: 50%; cursor: pointer; }
.button { border: none; background: #1d4ed8; color: #fff; padding: 10px 18px; border-radius: 6px; cursor: pointer; }
.disabledButton { background-color: #d8d8d8; cursor: not-allowed; }E impórtalo en el punto de entrada:
import './assets/boutique.css'
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')brand con el valor «Gekkode» y muéstralo en el título, delante del nombre del producto. Después cambia su valor en el código y comprueba que la página se actualiza sin recargar.Errores frecuentes
--default activa TypeScript: acabas con un src/main.ts y ficheros tsconfig. Lanza el comando sin flag y responde «no» a la pregunta sobre TypeScript.ref() devuelve un objeto. En el script escribe product.value, en la plantilla basta con {{ product }}, Vue desenvuelve la referencia.node -v antes de crear el proyecto.