
⚡ Vue 3:n perusteiden oppiminen: tyhjästä kansiosta komponentteihin
Katselet Vue 3:a ja näet tyylikkään frontend-kehyksen kolmen suuren joukosta. React, Angular, Vue: kuulostaa vakavalta. Sitten avaat ensimmäisen tutoriaalin, ja siellä odottavat vite, create-vue ja .vue-tiedostot kääntäjineen... Vaikka oikeasti voit ottaa Vuen käyttöön yhdellä <script>-rivillä ja alkaa kirjoittaa koodia heti. Ei bundlereita, ei JSX:ää, ei konfiguraatiohelvettiä.
Ero "haluan kokeilla" ja "kirjoitin komponentin" välillä on täällä lyhyempi kuin missään muualla. Mutta useimmat tutoriaalit eivät kuro tätä eroa umpeen; ne kertaavat dokumentaatiota sirpaleina antamatta kokonaiskuvaa. Näet hajanaisia syntaksinpaloja etkä hahmota, miten niistä tulee sovellus.
Tämä opas on juuri se polku, jonka me itse kuljimme Vuen kanssa: tyhjästä kansiosta komponentteihin, joilla on propseja. Kirjoitat ja ajat jokaisen rivin itse. Ei taikuutta, vain toimivaa koodia ja ymmärrys reaktiivisuudesta, Vuen tärkeimmästä supervoimasta.
💡 Pikakatsaus:
- Rakenna Vue-sovellus CDN:stä ja kiinnitä se DOM:iin: ensimmäinen toimiva instanssisi 5 minuutissa
- Käy läpi neljä keskeistä direktiiviä, v-for, v-if, v-on ja v-bind: minkä tahansa Vue-templaten tukipilarit
- Pura auki computed ja methods: milloin välimuistiin ja milloin kutsua
- Erota logiikka komponentteihin ja välitä dataa propsien avulla: askel kohti oikeaa arkkitehtuuria
Vue-sovelluksen luominen
Aloitetaan täysin nollasta. Ei create-vue:ta, vite:ä eikä vue-cli:tä, vain kansio ja kaksi tiedostoa.
Luo hakemisto ja tiedostot terminaalissa:
1 mkdir vue3-intro 2 cd vue3-intro 3 touch index.html app.js
Tai tee sama tiedostonhallinnan kautta. Avaa nyt index.html ja kirjoita runko:
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>
Kolme avainriviä. <script src="https://unpkg.com/vue@3/dist/vue.global.js"> lataa Vue 3:n CDN:stä. Tämä on nopein tapa päästä alkuun: kirjasto latautuu kuin tavallinen JavaScript-tiedosto, eikä build-vaihetta tarvita. <div id="app"> asettaa kiinnityspisteen: sen kohdan DOM:issa, jossa Vue "asuu". Kolmas rivi tuo sisään app.js-tiedoston, jossa määrittelemme logiikan.
Täytetään nyt 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')
Vue.createApp()-metodi luo sovellusinstanssin. Se vastaanottaa optio-olion; tässä määrittelimme course-ominaisuuden data()-funktion kautta. Vue tekee jokaisesta data():n palauttamasta ominaisuudesta reaktiivisen: kun arvo muuttuu, DOM päivittyy automaattisesti. Mitään manuaalista puun käsittelyä ei tarvita.
Mutta sovellus täytyy "kiinnittää" johonkin sivun elementtiin. Juuri tämän app.mount('#app') tekee. Ilman tätä riviä Vue ei reagoi mihinkään muutoksiin: instanssi on luotu, mutta sitä ei ole käynnistetty.
Enää täytyy näyttää ominaisuus HTML:ssä. Kirjoita <div id="app">-elementin sisään:
1 <h1>{{ course }}</h1>
Kaksoisaaltosulkeet {{ }} ovat interpolaatiota, ensisijainen tapa tulostaa dataa Vue-templaateissa. Vue korvaa kaiken {{ }}-merkkien sisällä olevan vastaavalla data():n ominaisuuden arvolla.

Avaa index.html selaimessasi. Sivu näyttää tekstin. Ensimmäinen sovelluksesi on valmis, ja kirjoitit sen itse sen sijaan, että olisit generoinut sen CLI:n kautta.
Listojen renderöinti
Oikeassa sovelluksessa työskentelet melkein aina taulukoiden kanssa: tuotteita, tageja, julkaisuja. Vue tarjoaa tähän v-for-direktiivin.
Lisätään tags-taulukko data():iin:
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 })
Ja HTML:ään lista:
1 <ul> 2 <li v-for="tag in tags">{{ tag }}</li> 3 </ul>
v-for-direktiivi iteroi tags-taulukon ja luo jokaiselle alkiolle oman <li>-elementtinsä. Silmukan sisällä oleva muuttuja tag on kulloinenkin alkio. Lopputulos näyttää tältä:

Tärkeä vivahde: kun iteroit taulukkoa, jokainen DOM-elementti tarvitsee uniikin avaimen. Vue käyttää sitä solmujen identiteetin seuraamiseen päivitysten aikana, mikä nopeuttaa uudelleenrenderöintiä ja estää tilaan liittyviä bugeja.
1 <ul> 2 <li v-for="(tag, index) in tags" :key="index">{{ tag }}</li> 3 </ul>
:key on lyhenne direktiivistä v-bind:key, joka sitoo key-attribuutin indeksin arvoon. Jos sinulla on oliotaulukko, esimerkiksi { id: 1, name: 'Vue' }, käytä avaimena id:tä indeksin sijaan. Indeksi muuttuu järjestystä vaihdettaessa, kun taas id pysyy samana, mikä tekee siitä luotettavamman.
Ehdollinen renderöinti
Usein sinun täytyy näyttää tai piilottaa elementti ehdon perusteella: ostopainike vain, jos kurssi on saatavilla. Vue hoitaa tämän v-if-direktiivillä.
Lisätään available-lippu data()-funktioon:
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 }
Ja käytetään sitä merkinnässä:
1 <p v-if="available">Course available for purchase!</p> 2 <p v-else>Unfortunately, the course is currently unavailable.</p>
v-if arvioi lainausmerkeissä olevan lausekkeen. Jos se on totuudellinen, ensimmäinen lohko renderöidään; muussa tapauksessa v-else astuu voimaan. Kokeile ajaa app.available = false selaimen konsolissa ja katso, kuinka sivu reagoi välittömästi.

v-if / v-else -direktiivien lisäksi on olemassa v-else-if ehtoketjuja varten ja v-show. Ero on perustavanlaatuinen: v-if poistaa elementin kokonaan DOM:sta, kun taas v-show ainoastaan vaihtaa display: none -tyylin päälle ja pois. Valitse v-if, kun ehto muuttuu harvoin. Käytä v-show-direktiiviä toistuvaan näyttämiseen ja piilottamiseen, kuten välilehdissä, joissa suorituskyvyllä on merkitystä.
Tapahtumien käsittely
v-on-direktiivi, tai lyhyesti @, kuuntelee DOM-tapahtumia: klikkauksia, syötteitä, hoveria. Kun tapahtuma laukeaa, Vue suorittaa määritellyn metodin tai lausekkeen.
Lisätään purchase-metodi sovelluksen optioihin:
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 })
methods-osio sisältää funktioita, joihin pääsee käsiksi templaatissa ja muissa metodeissa this-viittauksen kautta. Liitetään nyt kutsu painikkeeseen:
1 <button @click="purchase">Buy</button>

Yksinkertaisia toimintoja varten voit kirjoittaa koodia suoraan @click-direktiiviin:
1 <button @click="available = !available">Toggle availability</button>

Sisäinen koodi kuten tämä on kätevää lyhyissä toimenpiteissä, kuten lipun päälle tai pois kytkemisessä. Siirrä monimutkainen logiikka kuitenkin aina metodeihin; templaatin tulee pysyä luettavana. Yksinkertainen sääntö: counter += 1 on templaatissa ok, mutta kymmenen riviä ostoslogiikkaa kuuluu metodiin.
Attribuuttien sitominen
Attribuutit kuten src, href tai alt täytyy usein olla dynaamisia. Direktiivi v-bind, tai lyhyemmin :, sitoo attribuutin arvon Vue-lausekkeeseen.
Lisätään dataa kuvalle:
1 data() { 2 return { 3 // ...other properties 4 imgURL: 'https://catalins.tech/img', 5 imgDescription: 'Photo of a desk with a computer' 6 } 7 }
Sido ne templaatissa <img>-elementtiin:
1 <img :src="imgURL" :alt="imgDescription" width="500" height="350">
Täysi muoto olisi v-bind:src="imgURL"; kaksoispiste on vain syntaktista sokeria. Vue seuraa nyt muuttujia imgURL ja imgDescription: muuta niitä data()-funktiossa, ja sivun kuva päivittyy automaattisesti. Siinä reaktiivisuus käytännössä.

Sama periaate pätee attribuutteihin kuten :href, :disabled ja :class, sekä kaikkiin muihin. Kokeile itse: lisää linkki, jolla on dynaaminen href data()-funktiosta, ja varmista, että se toimii ilman yhtään ylimääräistä riviä.
Lasketut ominaisuudet
Joskus dataa täytyy muokata ennen näyttämistä: muotoilla hinta, yhdistää etu- ja sukunimi, tarkistaa ehto. Vue tarjoaa tähän computed-ominaisuudet.
Kuvittele, että haluat aina kuvauksen kuvalle, vaikka imgDescription-kenttä olisi tyhjä. Kirjoitetaan laskettu ominaisuus:
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 })
Käytä nyt laskettua ominaisuutta templaatissa raakadatan sijaan:
1 <img :src="imgURL" :alt="hasImageDescription" width="500" height="350">
Vue välimuistittaa computed-ominaisuuden tuloksen ja laskee sen uudelleen vain, kun sen riippuvuudet muuttuvat, tässä tapauksessa imgDescription. Tämä on tehokkaampaa kuin funktion kutsuminen jokaisella renderöinnillä.
Tärkeä sääntö: lasketut ominaisuudet on tarkoitettu datan näyttämiseen, ei sen muuttamiseen. Älä muuta sovelluksen tilaa computed-ominaisuuden sisällä; käytä siihen metodeja.
Metodit vs. lasketut ominaisuudet
Ero methods- ja computed-ominaisuuksien välillä tiivistyy yhteen kysymykseen: oletko muuttamassa dataa vai näyttämässä johdettua arvoa?
Lasketut ominaisuudet ovat esityskerrosta varten. Muotoilu, suodatus, ehtotarkistukset, merkkijonojen yhdistäminen. Ne ovat välimuistitettuja eikä niillä ole sivuvaikutuksia.
Metodit ovat toimintoja varten. Arvon muuttaminen data()-funktiossa, pyynnön lähettäminen, lipun kytkeminen. Niitä kutsutaan eksplisiittisesti ja ne voivat tehdä mitä tahansa.
Tyypillinen antisuunnittelumalli on this.course-muuttujan muokkaaminen computed-ominaisuuden sisällä. Laskettu ominaisuus reagoi course-muuttujan muutoksiin, mutta sen ei tulisi itse muuttaa sitä. Käytä aina metodia datan muuttamiseen. Anna templaatin kuvata "mitä näytetään", ei "miten se lasketaan".
Komponentit ja propsit
Kun sovellus kasvaa, kaiken pitäminen yhdessä tiedostossa käy hallitsemattomaksi. Vuen avulla voit pilkkoa käyttöliittymän komponenteiksi: eristetyiksi lohkoiksi, joilla on oma logiikkansa, mallineensa ja tyylinsä.
Luodaan ensimmäinen komponenttimme, CourseCard:
1 mkdir components 2 touch components/CourseCard.js
Määrittele komponentti tiedostossa components/CourseCard.js:
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 })
app.component()-metodin ensimmäinen argumentti on nimi, jota käytämme HTML:ssä tagina: <coursedisplay></coursedisplay>. Toinen on olio, joka sisältää data(), computed ja template -osiot eli komponentin "sisuskalut".
Otetaan nyt komponentti mukaan index.html-tiedostoon ja käytetään sitä:
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>
Toimme komponenttitiedoston, käytimme sitä mukautettuna tagina ja liitimme sovelluksen suoraan HTML:ään. Kurssilogiikka on nyt kapseloitu CourseCard-komponentin sisään, kun taas app.js vastaa ainoastaan instanssin luomisesta.
Propsit: datan välittäminen komponenttien välillä
Propsit (lyhenne sanasta properties) ovat mekanismi datan välittämiseen vanhemmalta komponentilta lapselle. Lapsikomponentti ilmoittaa, mitkä propsit se hyväksyy, ja vanhempi välittää ne attribuutteina.
Lisätään CourseCard-komponenttiin paid-props, joka kertoo, onko kurssi maksullinen vai ilmainen:
1 app.component('coursedisplay', { 2 props: { 3 paid: { 4 type: Boolean 5 } 6 }, 7 // ...rest of the configuration 8 })
Vanhempi, tässä tapauksessa app.js, välittää arvon:
1 const app = Vue.createApp({ 2 data() { 3 return { 4 allCourses: 1, 5 paid: true 6 } 7 } 8 })
Ja index.html-tiedostossa välitämme propsin:
1 <coursedisplay :paid="paid"></coursedisplay>
Vue validoi automaattisesti välitetyn arvon tyypin. Jos odotetaan Boolean-arvoa mutta saadaan merkkijono, kehys antaa varoituksen konsolissa. Tämä säästää sinut tyhmiltä virheiltä koodipohjan kasvaessa.
Jos haluat tehdä propsista pakollisen, lisää sen määrittelyyn required: true. Tällöin Vue valittaa, jos vanhempi ei välitä arvoa, joten saat tiedon ongelmasta ennen kuin se rikkoo käyttöliittymän.
Löydät tämän oppaan täydellisen koodin vue3-intro-repositoriosta GitHubissa, joka sisältää valmiit index.html-, app.js- ja components/CourseCard.js-tiedostot. Forkkaa se ja kokeile.
Aiheeseen liittyvä video
Vahvistaaksesi materiaalia käytännön kautta, katso Net Ninjan Vue 3 -kurssin ensimmäinen oppitunti; se täydentää tätä opasta mukavasti live-koodiesittelyllä:
⁉️🤔 Usein kysytyt kysymykset
Voinko käyttää Vue 3:a ilman bundleria tuotannossa?
Kyllä, sen sisällyttäminen CDN:n kautta (
unpkg.com/vue@3/dist/vue.global.js) toimii myös tuotannossa. Oikeisiin projekteihin suosittelemme kuitenkin siirtymistä Viteen: saat tree-shakingin, koodin jakamisen ja Single-File-komponentit, jotka yksinkertaistavat kehitystä dramaattisesti sovelluksen kasvaessa. Aloituspohjanpm create vue@latestpystyttää kaiken tämän minuutissa.
Miten v-if eroaa v-show:sta?
v-ifpoistaa elementin kokonaan DOM:sta, kun ehto on epätosi.v-showpitää elementin DOM:ssa mutta vaihtaa CSS-ominaisuudendisplay: none. Käytäv-if:ää, kun ehto muuttuu harvoin, esimerkiksi käyttäjäroolin mukaan. Käytäv-show:ta toistuvaan näyttämiseen ja piilottamiseen, kuten välilehdissä, joissa renderöintinopeudella on merkitystä ja haluat välttää solmujen uudelleenluonnin.
Onko:key pakollinen v-for:ssa?
Teknisesti
v-fortoimii ilman:key-määrettä, mutta Vue antaa varoituksen konsolissa. Ilman avainta kehys ei pysty seuraamaan, mikä DOM-elementti vastaa mitäkin data-alkiota, mikä johtaa bugeihin uudelleenjärjestelyn ja poistamisen yhteydessä. Määritä aina:keyyksilöllisellä tunnisteella, mieluitenid:llä datastasi eikä taulukon indeksillä.
Mikä on ero data():n ja computedin välillä?
data()tallentaa alkuperäisen tilan, "raakadatan".computedjohtaa siitä arvon näyttöä varten: muotoillun merkkijonon, suodatetun taulukon, validointituloksen. Laskennallinen ominaisuus päivittyy automaattisesti, kun sen riippuvuudet muuttuvat, ja se välimuistitetaan renderöintien välillä. Metodit sen sijaan kutsutaan joka kerta uudelleen, ja ne on tarkoitettu toimintoihin, ei näyttämiseen.
Voiko Options API:a ja Composition API:a sekoittaa?
Kyllä, voit käyttää molempia tyylejä samassa projektissa. Vue 3 tukee täysin Options API:a, kun taas Composition API on lisätyökalu monimutkaisiin skenaarioihin. Oppimista varten suosittelemme aloittamaan Options API:sta: se on jäsennellympi ja lähempänä ajatusmallia "komponentti on olio, jolla on optioita".
Mitä tehdä seuraavaksi: seuraava askeleesi Vue 3:n kanssa
Olet rakentanut ensimmäisen sovelluksesi, tutustunut direktiiveihin, laskennallisiin ominaisuuksiin ja komponentteihin. Tämä on perusta, jolle mikä tahansa projekti rakennetaan, aina laskeutumissivusta hallintapaneeliin.
Eteenpäin on kolme polkua. Ensimmäinen, vahvista osaamistasi käytännön kautta: nappaa julkinen API, kuten JSONPlaceholder, ja näytä lista postauksista computed-suodatuksella. Toinen, siirry Viteen ja .vue-tiedostoihin: Vuen virallinen dokumentaatio opastaa sinut create-vue:sta ensimmäiseen SFC:hen tunnissa. Kolmas, opettele Vue Router ja Pinia täysimittaisen SPA:n rakentamista varten.
Jos haluat kokeilla Vue:ta ilman minkäänlaista asennusta, katso artikkeli Vuen käyttöönotosta CDN:n kautta. Tämän oppaan aloituskoodi löytyy vue3-intro-repositoriosta; forkkaa se ja kokeile vapaasti.



