Vue 3-tutorial – een Vue-applicatie maken met create-vue
geverifieerd op 7 september 2026 · 5 min
Maak het project met npm create vue@latest, antwoord “nee” op TypeScript en draai daarna npm install en npm run dev. Een Vue-applicatie ontstaat uit createApp(App).mount('#app'), een waarde die je met ref() declareert, verschijnt in de template tussen dubbele accolades en werkt zichzelf bij.
Een Vue-applicatie is een instantie die je met createApp aanmaakt en aan een element van de pagina koppelt. Dit hoofdstuk zet het project op en zet daarna een eerste stuk data op het scherm.
Het project aanmaken
Vue heeft een officiële generator, create-vue, die een Vite-project opzet dat voor Vue is geconfigureerd. Open een terminal in de map waar je je projecten bewaart:
npm create vue@latestDe generator stelt een reeks vragen. Antwoord voor deze tutorial:
- Project name:
boutique-vue - TypeScript: Nee, we blijven bij JavaScript, om niet twee dingen tegelijk te moeten leren.
- JSX, Vue Router, Pinia, ESLint, Prettier: Nee. Die voegen we toe zodra ze nuttig zijn.
- Vitest: Ja als je tests wilt schrijven, anders Nee.
Veel tutorials geven npm create vue@latest -- --default om “snel klaar te zijn”. In create-vue 3.23 zet die vlag TypeScript aan: je krijgt een src/main.ts en tsconfig-bestanden, en dat is hier niet de bedoeling. Beantwoord liever de vragen.
Installeer de dependencies en start daarna de developmentserver:
Op Node 22 stopt de meegeleverde npm (10.9) met npm error Cannot read properties of null (reading 'edgesOut'), zowel bij een nieuw project als bij de code van deze tutorial. Werk npm bij voordat je installeert: npm install -g npm@latest. Node 24 heeft dit probleem niet.
cd boutique-vue
npm install
npm run devVite toont een adres, meestal http://localhost:5173/. Open het: de startpagina van het project verschijnt.
Wat de generator heeft aangemaakt
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/Drie bestanden tellen voorlopig. De generator maakt ook src/assets/main.css en base.css aan, de stijl van zijn startpagina: je kunt ze verwijderen, samen met de regel import './assets/main.css' waarmee src/main.js begint, zodra de CSS van de tutorial ze aan het einde van het hoofdstuk vervangt.
index.html bevat een lege container en laadt het entrypoint. Meer niet: de rest van de pagina wordt door Vue geproduceerd.
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>src/main.js maakt de applicatie op basis van het rootcomponent en mount haar in die container.
import './assets/main.css'
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')createApp(App) bouwt de instantie, .mount('#app') geeft haar het DOM-element dat ze mag beheren. Vanaf dat moment is alles binnen <div id="app"> van Vue.
Het eerste component
Een .vue-bestand is een single-file component: het script, de template en de stijl van hetzelfde stukje interface staan op één plek. Leeg src/App.vue en schrijf:
<script setup>
import { ref } from 'vue'
const product = ref('T-Shirt')
</script>
<template>
<div class="product-display">
<h1>{{ product }}</h1>
</div>
</template>Sla op: de browser toont “T-Shirt” zonder te herladen. Dat is de hot module replacement van Vite.
Dit bestand groeit aan tot het hoofdstuk over componenten, waar we het opknippen.
Wat die zeven regels doen
<script setup> zegt tegen Vue dat dit blok de logica van het component beschrijft. Alles wat je er op het eerste niveau declareert, is bruikbaar in de template, zonder ook maar iets te exporteren.
ref('T-Shirt') maakt een reactieve referentie: een doosje met een waarde erin dat Vue waarschuwt zodra die waarde verandert. In het script open je het doosje met .value:
const product = ref('T-Shirt')
console.log(product.value) // 'T-Shirt'
product.value = 'Pull' // de titel verandert meteen op het schermIn de template schrijf je daarentegen {{ product }} zonder .value: Vue pakt de referentie automatisch uit.
De dubbele accolades zijn een interpolatie. Ze accepteren elke JavaScript-expressie, niet alleen een variabelenaam:
<h1>{{ product }}</h1>
<h1>{{ product.toUpperCase() }}</h1>
<h1>{{ 'Notre ' + product }}</h1>Reactiviteit in de praktijk
Verander de beginwaarde in 'Pull' en sla op: de titel volgt. Je hebt geen enkele regel geschreven om de h1 op te zoeken en de inhoud ervan te wijzigen. Dat is de kern van Vue: jij beschrijft wat de pagina moet tonen op basis van de state, Vue zorgt voor de bijwerking.
Hetzelfde component zou je schrijven als export default { data() { return { product: 'T-Shirt' } } }, en het script zou de waarde benaderen via this.product. Met <script setup> bestaat this niet: er zijn alleen variabelen.
En de andere buildtools?
create-vue installeert Vite, de tool die het Vue-team aanraadt. Andere bundlers compileren .vue-bestanden ook: Parcel via @parcel/transformer-vue, of webpack met vue-loader.
Ze werken, maar ze zijn trager en je verlaat er de gebaande paden mee. Gemeten op 2 september 2026 op dezelfde applicatie met één component:
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 kBHet resultaat van npm run build is een map met statische bestanden. Wat daarin zit, bepaalt je vindbaarheid, een onderwerp dat apart aan bod komt.
Houd het bij Vite voor een nieuw project. De alternatieven zijn alleen te verdedigen als je bestaande buildketen er al van afhangt.
De CSS van deze tutorial
Om de applicatie er een beetje uit te laten zien, maak je src/assets/boutique.css aan met de paar regels die door alle hoofdstukken heen worden gebruikt:
.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; }En importeer het bestand in het entrypoint:
import './assets/boutique.css'
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')brand toe met de inhoud “Gekkode” en toon die in de titel, vóór de productnaam. Verander daarna de waarde in de code en controleer of de pagina zich zonder herladen bijwerkt.Veelgemaakte fouten
--default TypeScript aan: je krijgt een src/main.ts en tsconfig-bestanden. Draai het commando zonder vlag en antwoord “nee” op de TypeScript-vraag.n.value vergeten in het script | ref() geeft een object terug. In het script schrijf je product.value, in de template volstaat {{ product }}, want Vue pakt de referentie uit.node -v voordat je het project aanmaakt.