
⚡ Lär dig grunderna i Vue 3: från en tom mapp till komponenter
Du tittar på Vue 3 och ser ett snyggt frontend-ramverk från de tre stora. React, Angular, Vue: det låter seriöst. Sedan öppnar du den första handledningen, och där väntar vite, create-vue och .vue-filer med transpilatorer... Trots att du faktiskt kan inkludera Vue med en enda <script>-rad och börja skriva kod direkt. Inga paketerare, ingen JSX, inget konfigurationshelvete.
Avståndet mellan "jag vill testa" och "jag skrev en komponent" är kortare här än någon annanstans. Men de flesta handledningar minskar inte det avståndet; de återger dokumentationen i fragment utan att ge dig helhetsbilden. Du ser spridda syntaxbitar och kan inte lista ut hur de blir en applikation.
Den här guiden är den exakta väg vi själva tog med Vue: från en tom mapp till komponenter med props. Du kommer att skriva och köra varje rad själv. Ingen magi, bara fungerande kod och en förståelse för reaktivitet, Vues främsta superkraft.
💡 Snabb översikt:
- Bygg en Vue-app från en CDN och montera den i DOM:en: din första fungerande instans på 5 minuter
- Gå igenom fyra centrala direktiv, v-for, v-if, v-on och v-bind: grundpelarna i varje Vue-mall
- Bryt ner computed och methods: när du ska cacha och när du ska anropa
- Extrahera logik till komponenter och skicka data via props: ett steg mot riktig arkitektur
Skapa en Vue-app
Låt oss börja från absolut noll. Inget create-vue, vite eller vue-cli, bara en mapp med två filer.
Skapa mappen och filerna i din terminal:
1 mkdir vue3-intro 2 cd vue3-intro 3 touch index.html app.js
Eller gör samma sak via din filhanterare. Öppna nu index.html och skriv skelettet:
1 <!DOCTYPE html> 2 <html lang="ru"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> 7 <title>Vue 3 — first steps</title> 8 </head> 9 <body> 10 <div id="app"></div> 11 <script src="./app.js"></script> 12 </body> 13 </html>
Tre nyckelrader. <script src="https://unpkg.com/vue@3/dist/vue.global.js"> laddar Vue 3 från en CDN. Detta är det snabbaste sättet att komma igång: biblioteket laddas som en vanlig JavaScript-fil, inget byggsteg krävs. <div id="app"> sätter monteringspunkten: platsen i DOM:en där Vue ska "bo". Den tredje raden importerar app.js, där vi definierar logiken.
Nu fyller vi i app.js:
1 const app = Vue.createApp({ 2 data() { 3 return { 4 course: 'Introduction to Vue 3' 5 } 6 } 7 }) 8 9 app.mount('#app')
Metoden Vue.createApp() skapar en applikationsinstans. Den tar emot ett optionsobjekt; här deklarerade vi en course-egenskap via funktionen data(). Vue gör varje egenskap som returneras från data() reaktiv: när ett värde ändras uppdateras DOM:en automatiskt. Ingen manuell trädmanipulation behövs.
Men applikationen måste "fästas" vid ett element på sidan. Det är vad app.mount('#app') gör. Utan den här raden kommer Vue inte att reagera på några ändringar: instansen är skapad men inte startad.
Allt som återstår är att visa egenskapen i HTML:en. Inuti <div id="app">, skriv:
1 <h1>{{ course }}</h1>
Dubbla klammerparenteser {{ }} är interpolation, det primära sättet att mata ut data i Vue-mallar. Allt inuti {{ }} ersätts av Vue med motsvarande egenskapsvärde från data().

Öppna index.html i din webbläsare. Sidan visar texten. Din första app är klar, och du skrev den själv istället för att generera den via ett CLI.
Rendera listor
I en riktig applikation arbetar du nästan alltid med arrayer: produkter, taggar, inlägg. Vue tillhandahåller direktivet v-for för detta.
Låt oss lägga till en tags-array i data():
1 const app = Vue.createApp({ 2 data() { 3 return { 4 course: 'Introduction to Vue 3', 5 description: 'Basic guide to Vue 3 for beginners', 6 price: '$19.99', 7 tags: ['Vue', 'Frontend', 'JavaScript'] 8 } 9 } 10 })
Och i HTML:en, en lista:
1 <ul> 2 <li v-for="tag in tags">{{ tag }}</li> 3 </ul>
Direktivet v-for itererar över arrayen tags och skapar ett eget <li> för varje element. Variabeln tag inuti loopen är det aktuella elementet. Resultatet ser ut så här:

En viktig nyans: när du itererar över en array behöver varje DOM-element en unik nyckel. Vue använder den för att spåra nodidentitet under uppdateringar, vilket snabbar upp omrendering och förhindrar tillståndsrelaterade buggar.
1 <ul> 2 <li v-for="(tag, index) in tags" :key="index">{{ tag }}</li> 3 </ul>
:key är en förkortning för v-bind:key, som binder attributet key till indexvärdet. Om du har en array med objekt, till exempel { id: 1, name: 'Vue' }, använd id som nyckel istället för index. Indexet ändras vid omordning, medan id är stabilt, vilket gör det mer tillförlitligt.
Villkorsstyrd rendering
Du behöver ofta visa eller dölja ett element baserat på ett villkor: en köpknapp bara om kursen är tillgänglig. Vue hanterar detta med direktivet v-if.
Låt oss lägga till en available-flagga i data():
1 data() { 2 return { 3 course: 'Introduction to Vue 3', 4 description: 'Basic guide to Vue 3 for beginners', 5 price: '$19.99', 6 available: true, 7 tags: [ 8 { id: 1, name: 'Vue' }, 9 { id: 2, name: 'Frontend' }, 10 { id: 3, name: 'JavaScript' } 11 ] 12 } 13 }
Och använda den i märkspråket:
1 <p v-if="available">Course available for purchase!</p> 2 <p v-else>Unfortunately, the course is currently unavailable.</p>
v-if utvärderar uttrycket inom citattecken. Om det är sant, renderas det första blocket; annars tar v-else över. Testa att köra app.available = false i webbläsarkonsolen och se sidan reagera direkt.

Förutom v-if / v-else finns också v-else-if för villkorskedjor och v-show. Skillnaden är grundläggande: v-if tar bort elementet helt från DOM:en, medan v-show bara växlar display: none. Välj v-if när villkoret ändras sällan. Använd v-show för frekvent växling som flikar, där prestanda spelar roll.
Hantera händelser
Direktivet v-on, eller @ i kortform, lyssnar efter DOM-händelser: klick, inmatning, hover. När en händelse inträffar kör Vue den angivna metoden eller uttrycket.
Låt oss lägga till en purchase-metod i appalternativen:
1 const app = Vue.createApp({ 2 data() { 3 return { 4 course: 'Introduction to Vue 3', 5 description: 'Basic guide to Vue 3 for beginners', 6 price: '$19.99', 7 available: true, 8 tags: [ 9 { id: 1, name: 'Vue' }, 10 { id: 2, name: 'Frontend' }, 11 { id: 3, name: 'JavaScript' } 12 ] 13 } 14 }, 15 methods: { 16 purchase() { 17 console.log('Course purchased!') 18 } 19 } 20 })
Sektionen methods innehåller funktioner som är tillgängliga i mallen och andra metoder via this. Nu kopplar vi anropet till en knapp:
1 <button @click="purchase">Buy</button>

För enkla åtgärder kan du skriva kod direkt i @click:
1 <button @click="available = !available">Toggle availability</button>

Inline-kod som denna är praktisk för korta operationer som att växla en flagga. Men flytta alltid komplex logik till metoder; mallen ska förbli läsbar. En enkel regel: counter += 1 är okej i mallen, men tio rader inköpslogik hör hemma i en metod.
Bindning av attribut
Attribut som src, href eller alt behöver ofta vara dynamiska. Direktivet v-bind, eller : som kortform, binder ett attributvärde till ett Vue-uttryck.
Låt oss lägga till data för en bild:
1 data() { 2 return { 3 // ...other properties 4 imgURL: 'https://catalins.tech/img', 5 imgDescription: 'Photo of a desk with a computer' 6 } 7 }
I mallen binder vi dem till en <img>:
1 <img :src="imgURL" :alt="imgDescription" width="500" height="350">
Den fullständiga formen skulle vara v-bind:src="imgURL"; kolonet är bara syntaktiskt socker. Vue håller nu koll på imgURL och imgDescription: ändra dem i data(), så uppdateras bilden på sidan automatiskt. Det är reaktivitet i praktiken.

Samma princip gäller för attribut som :href, :disabled och :class, liksom alla andra. Testa själv: lägg till en länk med en dynamisk href från data() och kontrollera att den fungerar utan en enda extra rad.
Beräknade egenskaper
Ibland behöver data omvandlas innan visning: formatera ett pris, slå ihop för- och efternamn, kontrollera ett villkor. Vue tillhandahåller computed-egenskaper för detta.
Tänk dig att du alltid vill ha en bildbeskrivning, även om fältet imgDescription är tomt. Låt oss skriva en beräknad egenskap:
1 const app = Vue.createApp({ 2 data() { 3 return { 4 course: 'Introduction to Vue 3', 5 description: 'Basic guide to Vue 3 for beginners', 6 price: '$19.99', 7 available: true, 8 imgURL: 'https://catalins.tech/img', 9 imgDescription: 'Photo of a desk with a computer', 10 tags: [ 11 { id: 1, name: 'Vue' }, 12 { id: 2, name: 'Frontend' }, 13 { id: 3, name: 'JavaScript' } 14 ] 15 } 16 }, 17 computed: { 18 hasImageDescription() { 19 return this.imgDescription.length > 0 20 ? this.imgDescription 21 : 'Automatic image description' 22 } 23 } 24 })
Använd nu den beräknade egenskapen i mallen istället för rådatan:
1 <img :src="imgURL" :alt="hasImageDescription" width="500" height="350">
Vue cachar resultatet av en computed-egenskap och räknar om den endast när dess beroenden ändras, i vårt fall imgDescription. Detta är mer effektivt än att anropa en funktion vid varje rendering.
En viktig regel: beräknade egenskaper är till för att visa data, inte för att ändra den. Ändra inte applikationstillstånd inuti computed; använd metoder för det.
Metoder vs. beräknade egenskaper
Skillnaden mellan methods och computed kokar ner till en fråga: ändrar du data eller visar du ett härlett värde?
Beräknade egenskaper är till för presentationslagret. Formatering, filtrering, villkorskontroller, strängkonkatenering. De cachas och har inga sidoeffekter.
Metoder är till för åtgärder. Ändra ett värde i data(), skicka en förfrågan, växla en flagga. De anropas explicit och kan göra vad som helst.
Ett typiskt antimönster är att modifiera this.course inuti en computed-egenskap. En beräknad egenskap reagerar på ändringar i course men ska inte själv ändra det. Använd alltid en metod för att modifiera data. Låt mallen beskriva "vad som ska visas", inte "hur det ska beräknas".
Komponenter och props
När en applikation växer blir det ohållbart att ha allt i en enda fil. Vue låter dig bryta ner gränssnittet i komponenter: isolerade block med egen logik, mall och stilar.
Låt oss skapa vår första komponent, CourseCard:
1 mkdir components 2 touch components/CourseCard.js
I components/CourseCard.js definierar vi komponenten:
1 app.component('coursedisplay', { 2 data() { 3 return { 4 course: 'Introduction to Vue 3', 5 description: 'Basic guide to Vue 3 for beginners', 6 price: '$19.99', 7 available: true, 8 imgURL: 'https://catalins.tech/img', 9 imgDescription: 'Photo of a desk with a computer', 10 tags: [ 11 { id: 1, name: 'Vue' }, 12 { id: 2, name: 'Frontend' }, 13 { id: 3, name: 'JavaScript' } 14 ] 15 } 16 }, 17 computed: { 18 hasImageDescription() { 19 return this.imgDescription.length > 0 20 ? this.imgDescription 21 : 'Automatic image description' 22 } 23 }, 24 template: ` 25 <img :src="imgURL" :alt="hasImageDescription" width="500" height="350"> 26 <h1>{{ course }}</h1> 27 <p>{{ description }}</p> 28 <p>{{ price }}</p> 29 <button @click="available = !available">Buy</button> 30 <ul> 31 <li v-for="tag in tags" :key="tag.id">{{ tag.name }}</li> 32 </ul> 33 <p v-if="available">Course available for purchase!</p> 34 <p v-else>Unfortunately, the course is currently unavailable.</p> 35 ` 36 })
Första argumentet till app.component() är namnet vi använder i HTML som en tagg: <coursedisplay></coursedisplay>. Det andra är ett objekt med data(), computed och template, komponentens "interna delar".
Nu inkluderar vi komponenten i index.html och använder den:
1 <div id="app"> 2 <coursedisplay></coursedisplay> 3 </div> 4 <script src="./app.js"></script> 5 <script src="./components/CourseCard.js"></script> 6 <script> 7 const mountedApp = app.mount('#app') 8 </script>
Vi importerade komponentfilen, använde den som en anpassad tagg och monterade applikationen direkt i HTML:en. Kurslogiken är nu inkapslad inuti CourseCard, medan app.js bara ansvarar för att skapa instansen.
Props: skicka data mellan komponenter
Props (kort för properties) är mekanismen för att skicka data från en föräldrakomponent till ett barn. Barnkomponenten deklarerar vilka props den tar emot, och föräldern skickar dem som attribut.
Låt oss lägga till en paid-prop i CourseCard som anger om kursen är betald eller gratis:
1 app.component('coursedisplay', { 2 props: { 3 paid: { 4 type: Boolean 5 } 6 }, 7 // ...rest of the configuration 8 })
Föräldern, i vårt fall app.js, skickar värdet:
1 const app = Vue.createApp({ 2 data() { 3 return { 4 allCourses: 1, 5 paid: true 6 } 7 } 8 })
Och i index.html skickar vi propen via:
1 <coursedisplay :paid="paid"></coursedisplay>
Vue validerar automatiskt typen på det skickade värdet. Om en Boolean förväntas men en sträng tas emot, kommer ramverket att ge en varning i konsolen. Detta räddar dig från dumma misstag när kodbasen växer.
För att göra en prop obligatorisk, lägg till required: true i dess definition. Vue kommer då att klaga om föräldern inte skickar ett värde, så du får reda på problemet innan det förstör gränssnittet.
Du hittar den kompletta koden för denna guide i vue3-intro-repositoriet på GitHub, som innehåller de färdiga filerna index.html, app.js och components/CourseCard.js. Forka det och experimentera.
Relaterad video
För att befästa materialet genom praktik, titta på den första lektionen från Net Ninjas Vue 3-kurs; den kompletterar denna guide fint med en live-kodgenomgång:
⁉️🤔 Vanliga frågor
Kan jag använda Vue 3 utan en bundler i produktion?
Ja, att inkludera det via CDN (
unpkg.com/vue@3/dist/vue.global.js) fungerar också i produktion. Men för riktiga projekt rekommenderar vi att byta till Vite: du får tree-shaking, code-splitting och Single-File Components, vilket dramatiskt förenklar utvecklingen när applikationen växer. Startmallennpm create vue@latestsätter upp allt detta på en minut.
Hur skiljer sig v-if från v-show?
v-iftar bort elementet helt från DOM:en när villkoret är falskt.v-showbehåller elementet i DOM:en men växlar CSS-egenskapendisplay: none. Användv-ifnär villkoret ändras sällan, till exempel användarroll. Användv-showför frekvent växling som flikar, där renderingshastighet spelar roll och du vill undvika att återskapa noder.
Är:key obligatoriskt i v-for?
Tekniskt sett fungerar
v-forutan:key, men Vue kommer att ge en varning i konsolen. Utan en nyckel kan ramverket inte spåra vilket DOM-element som motsvarar vilket dataelement, vilket leder till buggar vid omordning och borttagning. Ange alltid:keymed en unik identifierare,idfrån din data snarare än arrayindex.
Vad är skillnaden mellan data() och computed?
data()lagrar det ursprungliga tillståndet, den "råa" datan.computedhärleder ett värde från det för visning: en formaterad sträng, en filtrerad array, ett valideringsresultat. En computed-egenskap uppdateras automatiskt när dess beroenden ändras och cachas mellan renderingar. Metoder å andra sidan anropas på nytt varje gång och är avsedda för åtgärder, inte för visning.
Kan man blanda Options API och Composition API?
Ja, du kan använda båda stilarna i ett och samma projekt. Vue 3 har fullt stöd för Options API, medan Composition API är ett extra verktyg för komplexa scenarier. För inlärning rekommenderar vi att börja med Options API: det är mer strukturerat och ligger närmare den mentala modellen att "en komponent är ett objekt med options".
Vad du ska göra härnäst: ditt nästa steg med Vue 3
Du har byggt din första app, utforskat direktiv, computed-egenskaper och komponenter. Detta är grunden som alla projekt byggs på, från en landningssida till en adminpanel.
Det finns tre vägar framåt. För det första, befäst genom praktik: ta ett publikt API som JSONPlaceholder och visa en lista med inlägg med filtrering via computed. För det andra, gå över till Vite och .vue-filer: den officiella Vue 3-dokumentationen leder dig från create-vue till din första SFC på en timme. För det tredje, lär dig Vue Router och Pinia för att bygga en fullfjädrad SPA.
Om du vill testa Vue utan någon installation alls, kolla in artikeln om att inkludera Vue via CDN. Och startkoden från den här guiden finns i vue3-intro-repot; forka det och experimentera.



