Vue 3 segédlet

Feladatból indulsz, működő kódot másolsz ki. Egy közös példán, egy teendőlistán át, a hivatalos dokumentáció ajánlott útján: Composition API és <script setup>.

Vue
3.5.43, stabil 2026. szeptember 17.
Stílus
Composition API, <script setup>
Indítás
npm create vue@latest Vite
Ellenőrizve

Indulás

Üres gépről futó projektig, hat lépésben.

  1. Node.js telepítése

    A Vue fejlesztőeszközei -en futnak. A projektgenerátor (create-vue 3.24) a 22.18-as vagy újabb 22-es, illetve a 24.12-es vagy újabb Node-ot kéri. Letöltés: nodejs.org (új lapon nyílik). Ellenőrzés a terminálban:

    Terminál
    node -v
  2. Projekt létrehozása

    A hivatalos generátor egy -alapú projektet készít. A @latest nem hagyható el, különben az npm egy régi, gyorsítótárazott változatot is futtathat. A varázsló a projekt nevét és a kiegészítőket kérdezi (pl. TypeScript, Router, Pinia, ESLint); kezdéshez mindenre mehet a „Nem”, később bármelyik hozzáadható.

    Terminál
    npm create vue@latest
  3. Indítás

    Belépsz a mappába, telepíted a függőségeket, és elindítod a fejlesztői szervert. A Vite kiírja a címet (alapból http://localhost:5173); mentéskor a böngésző azonnal frissül. A kész, feltölthető oldalt az npm run build teszi a dist mappába.

    Terminál
    cd teendolista
    npm install
    npm run dev
  4. Mi van a mappában?

    A fontosabb fájlok. A saját kódod szinte mind az src mappába kerül: a App.vue-ba és a components alá. A projektet érdemes rögtön Gitbe tenni: a lépéseket a Git-kézikönyv mutatja.

    teendolista/
    teendolista/
    ├─ index.html        egy üres <div id="app">
    ├─ package.json      függőségek és parancsok
    ├─ vite.config.js    a Vite beállításai
    ├─ public/           változatlanul kimásolt fájlok
    └─ src/
       ├─ main.js        itt indul az alkalmazás
       ├─ App.vue        a gyökérkomponens
       ├─ assets/        képek, CSS
       └─ components/    a saját komponenseid
  5. Egy .vue fájl három része

    Egy .vue fájl egy : a <script setup> a logika, a <template> a HTML, a <style scoped> a csak erre a komponensre ható CSS. A setup miatt a scriptben létrehozott változókat és importokat a sablon közvetlenül látja.

    App.vue
    <script setup>
    import { ref } from 'vue'
    
    const cim = ref('Teendőim')
    </script>
    
    <template>
      <h1>{{ cim }}</h1>
    </template>
    
    <style scoped>
    h1 {
      font-size: 2rem;
    }
    </style>
  6. Az alkalmazás belépési pontja

    A main.js létrehozza az alkalmazást az App.vue-ból, és beleteszi az index.html üres #app elemébe. A generátor ezt megírja, általában nem kell hozzányúlni.

    src/main.js
    import { createApp } from 'vue'
    import App from './App.vue'
    
    createApp(App).mount('#app')

Telepítés nélkül, egyetlen HTML-fájlban is kipróbálható, ha a Vue-t egy <script> tölti be. Így nincs .vue fájl és <script setup>, ezért ez az oldal a fenti utat követi. Leírás: a hivatalos útmutató indulási része (angolul) (új lapon nyílik).

Receptek

Minden recept egy feladat. A példák ugyanarra a teendőlistára épülnek, és kimásolva futnak.

Adat

Hol él az állapot, és mitől frissül az oldal.

Adatot tárolni, ami frissíti az oldalt

ref()

A ref() egy doboz. Ha a tartalma megváltozik, a Vue frissíti az oldal azon részeit, ahol használod. Sima JS-ben ehhez textContent-et írnál át kézzel. Ez a adat.

Scriptben darab.value, a sablonban csak darab. A const nem gond: a doboz marad ugyanaz, csak a tartalma változik. Ha elmarad a .value

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

const darab = ref(0)

function novel() {
  darab.value++
}
</script>

<template>
  <button @click="novel">Kattintások: {{ darab }}</button>
</template>

Összetartozó adatokat egy objektumban tartani

reactive()

A reactive() egy objektumot tesz reaktívvá, és nem kell hozzá .value. Két korlátja van: az egész objektumot nem cserélheted le, és ha szétszeded (destrukturálod), a darabok már nem frissülnek. Kezdőként a ref elég mindenre, objektumra is.

Szétszedés után nem frissül?

UjTeendo.vue · script
import { reactive } from 'vue'

const urlap = reactive({
  szoveg: '',
  hatarido: null,
})

urlap.szoveg = 'Bevásárlás'

Más adatokból számolt érték

computed()

Ha egy érték kiszámolható más adatokból (szűrt lista, összeg, teljes név), ne tárold külön. A computed() megjegyzi az eredményt, és csak akkor számol újra, ha a forrás változik. Csak olvasásra való: ne írj benne más adatot.

Sablonban: {{ hatralevo.length }} teendő van hátra. Scriptben itt is hatralevo.value.

TeendoLista.vue · script
import { ref, computed } from 'vue'

const teendok = ref([
  { id: 1, szoveg: 'Tej', kesz: true },
  { id: 2, szoveg: 'Kenyér', kesz: false },
])

const hatralevo = computed(() => teendok.value.filter(t => !t.kesz))

Kódot futtatni, amikor egy adat változik

watch()

A watch() egy adatot figyel, és változáskor lefuttat egy függvényt. való: mentés, szerverhívás, címsor átírása. Ha csak egy értéket akarsz kiszámolni, az computed. A watchEffect() azonnal lefut, és magától figyel mindent, amit olvas.

Objektum egy mezőjét függvénnyel figyeld: watch(() => urlap.szoveg, …). Belső változásokhoz: { deep: true }, azonnali első futáshoz: { immediate: true }.

Kereso.vue · script
import { ref, watch, watchEffect } from 'vue'

const kereses = ref('')

watch(kereses, (uj, regi) => {
  console.log(regi, '->', uj)
})

watchEffect(() => {
  document.title = 'Keresés: ' + kereses.value
})

Sablon

Mit és hogyan rajzol ki a <template>.

Adatot kiírni a szövegbe

{{ }}

A dupla kapcsos zárójelbe bármilyen JavaScript- kerülhet, az eredménye szövegként jelenik meg, és magától frissül. Utasítás (if, let, for) nem.

A HTML-t szövegként írja ki, ez véd a beszúrt kód ellen. Ha tényleg HTML kell, a v-html való rá, de csak megbízható tartalommal.

TeendoLista.vue
<template>
  <h2>{{ cim }}</h2>
  <p>{{ teendok.length }} teendő, ebből {{ hatralevo.length }} van hátra</p>
  <p>{{ surgos ? 'Sürgős!' : 'Ráér' }}</p>
</template>

Attribútumot, osztályt, stílust adatból adni

v-bind :

Attribútumba a {{ }} nem működik, oda a v-bind kell, röviden kettőspont. Kettősponttal az idézőjelben JS-kifejezés van: src="kep" a „kep” szöveg, :src="kep" a kep változó értéke.

Ha a változó neve egyezik az attribútuméval, elég a rövid alak: :id ugyanaz, mint :id="id" (Vue 3.4 óta).

TeendoElem.vue
<template>
  <img :src="kep" :alt="leiras">
  <button :disabled="!uj.trim()">Hozzáadás</button>
  <li :class="{ kesz: teendo.kesz, surgos: teendo.surgos }">{{ teendo.szoveg }}</li>
  <div :style="{ width: szazalek + '%' }"></div>
</template>

Kattintásra, Enterre, beküldésre reagálni

v-on @

Ugyanaz, mint az addEventListener, csak a sablonban. A v-on rövidítése a @. Utána az esemény neve, majd módosítók: .prevent (nem tölti újra az oldalt), .stop, .once, billentyűk: .enter, .esc.

Paraméterrel: @click="torol(teendo.id)". Az eseményobjektum ilyenkor $event néven érhető el.

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

const uj = ref('')
const teendok = ref([])

function hozzaad() {
  if (!uj.value.trim()) return
  teendok.value.push({ id: Date.now(), szoveg: uj.value, kesz: false })
  uj.value = ''
}
</script>

<template>
  <form @submit.prevent="hozzaad">
    <input v-model="uj" @keyup.esc="uj = ''">
    <button>Hozzáadás</button>
  </form>
</template>

Elemet feltételhez kötni

v-if v-show

Mint az if / else if / else, csak elemekre. Hamis feltételnél az elem be sem kerül a DOM-ba. A v-show az elemet megtartja, csak elrejti (display: none): gyakori ki-be kapcsolgatásnál ez a jobb.

A v-else és a v-else-if közvetlenül a v-if után álljon. Mi történik, ha nem?

TeendoLista.vue
<template>
  <p v-if="teendok.length === 0">Nincs teendő.</p>
  <p v-else-if="hatralevo.length === 0">Minden kész.</p>
  <p v-else>{{ hatralevo.length }} teendő van hátra.</p>

  <div v-show="nyitva">Beállítások</div>
</template>

Listát kirajzolni

v-for :key

Egy elemből annyi példányt rajzol, ahány eleme a tömbnek van. A :key minden elemnek egyedi, állandó azonosító (pl. id): ebből tudja a Vue, melyik sor melyik, ha a lista változik. Számtartományhoz: v-for="n in 5" (1-től 5-ig).

Indexet csak akkor használj kulcsnak, ha a lista soha nem rendeződik át. Szűréshez ne tedd a v-if-et ugyanarra az elemre. Miért?

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

const teendok = ref([
  { id: 1, szoveg: 'Tej' },
  { id: 2, szoveg: 'Kenyér' },
])

function torol(id) {
  teendok.value = teendok.value.filter(t => t.id !== id)
}
</script>

<template>
  <ol>
    <li v-for="(teendo, i) in teendok" :key="teendo.id">
      {{ i + 1 }}. {{ teendo.szoveg }}
      <button @click="torol(teendo.id)">Törlés</button>
    </li>
  </ol>
</template>

Űrlapmezőt adathoz kötni

v-model

Összeköt egy mezőt egy ref-fel, mindkét irányba: amit beírnak, bekerül a változóba, és ha a változót írod át, a mező is követi. Módosítók: .trim (szóközök le), .number (számmá alakít), .lazy (csak mezőelhagyáskor frissít).

Saját komponensen is működik: defineModel.

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

const szoveg = ref('')
const darab = ref(1)
const kesz = ref(false)
const kategoria = ref('otthon')
</script>

<template>
  <input v-model.trim="szoveg">
  <input v-model.number="darab" type="number">
  <label><input v-model="kesz" type="checkbox"> Kész</label>
  <select v-model="kategoria">
    <option value="otthon">Otthon</option>
    <option value="munka">Munka</option>
  </select>
</template>

Komponensek

Darabokra bontás, és hogyan beszélnek egymással.

Saját komponenst használni

import

Egy .vue fájl egy . Másikban úgy használod, hogy a <script setup>-ban importálod, és a sablonban leírod a nevét, mint egy HTML-elemet. Regisztrálni nem kell.

A fájl- és komponensnév PascalCase (nagy kezdőbetűk). Nem jelenik meg a komponens?

App.vue
<script setup>
import TeendoLista from './components/TeendoLista.vue'
</script>

<template>
  <TeendoLista />
</template>

Adatot átadni a gyerekkomponensnek

defineProps()

A szülő úgy ad adatot a gyereknek, mint egy HTML-attribútumot. A gyerek a defineProps()-szal mondja meg, mit vár. Vue 3.5 óta szét is szedheted, és az alapértéket ott adhatod meg; a darabok reaktívak maradnak. A gyerek a propot csak olvassa.

Szétszedett propot függvénnyel figyelj: watch(() => szoveg, …). 3.5 előtt: const props = defineProps(…), majd props.szoveg. Átírnád a propot?

TeendoElem.vue
<script setup>
const { szoveg, kesz, cimke = 'általános' } = defineProps({
  szoveg: { type: String, required: true },
  kesz: Boolean,
  cimke: String,
})
</script>

<template>
  <li :class="{ kesz }">{{ szoveg }} <small>{{ cimke }}</small></li>
</template>
TeendoLista.vue
<TeendoElem
  v-for="teendo in teendok"
  :key="teendo.id"
  :szoveg="teendo.szoveg"
  :kesz="teendo.kesz"
/>

Szólni a szülőnek, hogy történt valami

defineEmits()

Visszafelé a gyerek eseményt küld, a szülő pedig @-cal figyeli, mint egy kattintást, csak saját névvel. Az esemény mellé adatot is küldhetsz: emit('atnevezes', ujNev), a szülő ezt paraméterként kapja.

TeendoElem.vue
<script setup>
const { szoveg } = defineProps({ szoveg: String })
const emit = defineEmits(['torles'])
</script>

<template>
  <li>
    {{ szoveg }}
    <button @click="emit('torles')">Törlés</button>
  </li>
</template>
TeendoLista.vue
<TeendoElem
  v-for="teendo in teendok"
  :key="teendo.id"
  :szoveg="teendo.szoveg"
  @torles="torol(teendo.id)"
/>

v-model a saját komponensen

defineModel()

A defineModel() egy refet ad, ami a szülő v-model-jéhez kötődik: olvasva a szülő értékét kapod, írva visszaküldöd. Enélkül külön prop és emit kellene. Vue 3.4 óta van.

Több is lehet névvel: defineModel('kesz') a gyerekben, v-model:kesz="…" a szülőben.

SzovegMezo.vue
<script setup>
const szoveg = defineModel({ type: String, default: '' })
</script>

<template>
  <input v-model="szoveg" class="mezo">
</template>
UjTeendo.vue
<script setup>
import { ref } from 'vue'
import SzovegMezo from './SzovegMezo.vue'

const uj = ref('')
</script>

<template>
  <SzovegMezo v-model="uj" />
  <p>Beírva: {{ uj }}</p>
</template>

Tartalmat átadni a komponensnek

<slot>

Amit a komponens címkéi közé írsz, az a <slot> helyére kerül. Keretekhez, kártyákhoz, felugró ablakokhoz való. Több helyhez nevet adsz, és a szülő <template #nev>-vel tölti ki.

A <slot> tartalma az alapérték: akkor látszik, ha a szülő nem ad semmit.

Kartya.vue
<template>
  <section class="kartya">
    <header>
      <slot name="fejlec">Teendők</slot>
    </header>
    <slot />
  </section>
</template>
App.vue
<Kartya>
  <template #fejlec>Mai teendők</template>
  <TeendoLista />
</Kartya>

Adatot sok szinttel lejjebb adni

provide / inject

Ha egy adatot öt szinten át kellene propként továbbadni, a felső komponens provide()-dal kínálja, bármelyik leszármazott inject()-tel kéri. Refet adj át, így a változás lent is látszik.

Az egész alkalmazás közös állapotához a hivatalos megoldás a Pinia.

App.vue · script
import { ref, provide } from 'vue'

const tema = ref('sotet')
provide('tema', tema)
Gomb.vue · script
import { inject } from 'vue'

const tema = inject('tema')

Életciklus és újrahasznosítás

Mikor fut a kód, hogyan éred el a DOM-ot, hogyan szervezed ki.

Adatot betölteni, amikor a komponens megjelenik

onMounted()

Az onMounted() akkor fut, amikor a komponens már az oldalon van. Ez az egyik pontja. Betöltésnél három állapotot kezelj: tölt, kész, hiba.

Takarításhoz (időzítő, eseményfigyelő) az onUnmounted() való. A horgot mindig a script tetején, szinkron hívd. Miért?

TeendoLista.vue
<script setup>
import { ref, onMounted } from 'vue'

const teendok = ref([])
const allapot = ref('tolt')

onMounted(async () => {
  try {
    const valasz = await fetch('/api/teendok')
    if (!valasz.ok) throw new Error('HTTP ' + valasz.status)
    teendok.value = await valasz.json()
    allapot.value = 'kesz'
  } catch {
    allapot.value = 'hiba'
  }
})
</script>

<template>
  <p v-if="allapot === 'tolt'">Betöltés…</p>
  <p v-else-if="allapot === 'hiba'">Nem sikerült betölteni.</p>
  <ul v-else>
    <li v-for="t in teendok" :key="t.id">{{ t.szoveg }}</li>
  </ul>
</template>

DOM-elemet elérni, pl. fókuszálni

useTemplateRef()

Ha magát az elemet kell elérned (fókusz, görgetés, méret), adj neki ref="nev" attribútumot, és kérd el a useTemplateRef('nev')-vel. Az értéke csak megjelenés után van meg, előtte null. Vue 3.5 óta van.

3.5 előtt: const mezo = ref(null), és a sablonban ref="mezo", ugyanazzal a névvel.

UjTeendo.vue
<script setup>
import { useTemplateRef, onMounted } from 'vue'

const mezo = useTemplateRef('uj-mezo')

onMounted(() => {
  mezo.value.focus()
})
</script>

<template>
  <input ref="uj-mezo">
</template>

Megvárni, hogy a DOM frissüljön

nextTick()

A Vue a változásokat összegyűjti, és egyszerre írja ki. Ezért közvetlenül az adat átírása után a DOM még a régi. Az await nextTick() után már az új.

TeendoLista.vue · script
import { ref, nextTick, useTemplateRef } from 'vue'

const teendok = ref([])
const lista = useTemplateRef('lista')

async function hozzaad(szoveg) {
  teendok.value.push({ id: Date.now(), szoveg, kesz: false })
  await nextTick()
  lista.value.lastElementChild.scrollIntoView()
}

Logikát kiszervezni és újrahasznosítani

useValami()

A egy sima függvény, ami Vue-s reaktivitást használ, és use-zal kezdődik a neve. Ez itt a listát a böngésző tárhelyére menti, és bármelyik komponensben egy sorral használható.

A composable-t is a script tetején, szinkron hívd, ugyanúgy, mint az onMounted-et.

useTarolt.js
import { ref, watch } from 'vue'

export function useTarolt(kulcs, alap) {
  const mentett = localStorage.getItem(kulcs)
  const ertek = ref(mentett ? JSON.parse(mentett) : alap)

  watch(ertek, uj => {
    localStorage.setItem(kulcs, JSON.stringify(uj))
  }, { deep: true })

  return ertek
}
TeendoLista.vue · script
import { useTarolt } from '../composables/useTarolt.js'

const teendok = useTarolt('teendok', [])

Gyakori hibák

A konzol üzenete angolul, szó szerint, ahogy a Vue 3.5 kiírja; mellette, hogy mit jelent, és hogyan javítsd. Az üzenetet a fenti keresőbe is bemásolhatod.

Elmarad a .value a scriptben

ref()
Üzenet

Nincs: csendben hibás az eredmény.

A ref egy doboz, nem maga a szám. A darab++ a dobozt írná felül, ami const-nál hiba (a fordító vagy a böngésző szól). A darab > 5 pedig a dobozt hasonlítja, ezért mindig hamis, Vue-üzenet nélkül.

RosszSzamlalo.vue
const darab = ref(0)

function novel() {
  darab++
}

if (darab > 5) console.log('sok')
JóSzamlalo.vue
const darab = ref(0)

function novel() {
  darab.value++
}

if (darab.value > 5) console.log('sok')

Üres marad a kiírás: .value a sablonban

{{ }}
Üzenet

Nincs: csendben hibás az eredmény.

A sablonban a Vue a felső szintű refeket magától kibontja. A darab.value ott már a szám .value-ja, vagyis undefined, ezért üres. Kivétel: ha a ref egy sima objektum mezőjében van, azt nem bontja ki.

RosszSzamlalo.vue
<template>
  <p>{{ darab.value }}</p>
</template>
JóSzamlalo.vue
<template>
  <p>{{ darab }}</p>
</template>

Szám vagy változó helyett szöveg megy át

v-bind :
Üzenet [Vue warn]: Invalid prop: type check failed for prop "db". Expected Number with value 3, got String with value "3".

Kettőspont nélkül az idézőjelben sima szöveg van: db="3" a „3” sztring, src="kep" a „kep” szó. Kettősponttal JS-kifejezés: szám, változó, logikai érték.

RosszTeendoLista.vue
<template>
  <TeendoSzamlalo db="3" />
  <img src="kep">
</template>
JóTeendoLista.vue
<template>
  <TeendoSzamlalo :db="3" />
  <img :src="kep">
</template>

Hiányzó vagy ismétlődő :key a listában

v-for
Üzenet Elements in iteration expect to have 'v-bind:key' directives. [Vue warn]: Duplicate keys found during update: 1 Make sure keys are unique.

Az első az ESLint (eslint-plugin-vue) üzenete, a második a Vue-é.

A kulcsból tudja a Vue, melyik sor melyik, amikor a lista változik. Hiányzó vagy ismétlődő kulcsnál rossz sor kaphatja meg a mező tartalmát vagy az animációt. Kulcs legyen egyedi és állandó, pl. id.

RosszTeendoLista.vue
<ul>
  <li v-for="teendo in teendok" :key="teendo.kategoria">
    {{ teendo.szoveg }}
  </li>
</ul>
JóTeendoLista.vue
<ul>
  <li v-for="teendo in teendok" :key="teendo.id">
    {{ teendo.szoveg }}
  </li>
</ul>

v-if és v-for ugyanazon az elemen

v-for v-if
Üzenet [Vue warn]: Property "teendo" was accessed during render but is not defined on instance.

A Vue 3-ban a v-if fut előbb, amikor a teendo még nem létezik. (A Vue 2-ben fordítva volt, ezért régi példákban még látni.) Szűrj egy computed-del, és azon menj végig.

RosszTeendoLista.vue
<ul>
  <li v-for="teendo in teendok"
      v-if="!teendo.kesz"
      :key="teendo.id">
    {{ teendo.szoveg }}
  </li>
</ul>
JóTeendoLista.vue
<ul>
  <li v-for="teendo in hatralevo"
      :key="teendo.id">
    {{ teendo.szoveg }}
  </li>
</ul>

A komponens nem jelenik meg

import
Üzenet [Vue warn]: Failed to resolve component: TeendoElem If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.

A sablonban használt nevet a Vue nem találja: elmaradt az import, el van írva, vagy rossz az útvonal. A <script setup>-ban az import egyben a regisztráció is.

RosszApp.vue
<script setup>
import { ref } from 'vue'
</script>

<template>
  <TeendoElem />
</template>
JóApp.vue
<script setup>
import TeendoElem from './components/TeendoElem.vue'
</script>

<template>
  <TeendoElem />
</template>

A gyerek átírná a propot

defineProps()
Üzenet [Vue warn]: Set operation on key "kesz" failed: target is readonly. Cannot assign to destructured props as they are readonly.

Az első futás közben jön, a második fordításkor, ha szétszedett propot írsz át.

A prop a szülőé, a gyerek csak olvassa. Ha a gyereknek is módosítania kell, legyen defineModel (a szülőben v-model:kesz), vagy küldjön eseményt.

RosszTeendoElem.vue · script
const props = defineProps({ kesz: Boolean })

function valt() {
  props.kesz = !props.kesz
}
JóTeendoElem.vue · script
const kesz = defineModel('kesz', { type: Boolean })

function valt() {
  kesz.value = !kesz.value
}

v-model egy propon

v-model
Üzenet v-model cannot be used on a prop, because local prop bindings are not writable.

Fordítási hiba: a Vite a böngészőben és a terminálban is kiírja.

A v-model írná a változót, a prop viszont csak olvasható. Saját beviteli komponensben a defineModel() való erre.

RosszSzovegMezo.vue
<script setup>
const { szoveg } = defineProps({ szoveg: String })
</script>

<template>
  <input v-model="szoveg">
</template>
JóSzovegMezo.vue
<script setup>
const szoveg = defineModel()
</script>

<template>
  <input v-model="szoveg">
</template>

Szétszedés után nem frissül

reactive()
Üzenet

Nincs: csendben hibás az eredmény.

A reactive objektumból kiszedett mezők sima értékek, a kapcsolat megszakad. Használd a toRefs()-t, vagy hivatkozz a mezőre: urlap.szoveg.

RosszUjTeendo.vue · script
import { reactive } from 'vue'

const urlap = reactive({ szoveg: '', kesz: false })
const { szoveg, kesz } = urlap
JóUjTeendo.vue · script
import { reactive, toRefs } from 'vue'

const urlap = reactive({ szoveg: '', kesz: false })
const { szoveg, kesz } = toRefs(urlap)

Életciklus-horog rossz helyen

onMounted()
Üzenet [Vue warn]: onMounted is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup(). If you are using async setup(), make sure to register lifecycle hooks before the first await statement.

Az onMounted és a többi horog (és az ezeket hívó composable) csak a komponens felállítása közben regisztrálható: a <script setup> tetején, szinkron. Eseménykezelőben, időzítőben vagy saját async függvényben egy await után már nincs „aktív komponens”.

RosszUjTeendo.vue · script
import { onMounted } from 'vue'

function megnyit() {
  onMounted(() => {
    mezo.value.focus()
  })
}
JóUjTeendo.vue · script
import { onMounted } from 'vue'

onMounted(() => {
  mezo.value.focus()
})

A v-else nem a v-if után áll

v-if
Üzenet v-else/v-else-if has no adjacent v-if or v-else-if.

Fordítási hiba.

A v-else és a v-else-if csak közvetlenül egy v-if-es testvérelem után állhat. Közé semmi nem kerülhet, megjegyzés sem.

RosszTeendoLista.vue
<p v-if="teendok.length">Van teendő.</p>
<hr>
<p v-else>Nincs teendő.</p>
JóTeendoLista.vue
<p v-if="teendok.length">Van teendő.</p>
<p v-else>Nincs teendő.</p>
<hr>

Régi kódot olvasol?

Tutorialban, régi projektben még gyakori az Options API és a Vue 2. Az Options API a Vue 3-ban is teljes értékű; a hivatalos útmutató teljes alkalmazáshoz a Composition API-t és az egyfájlos komponenst ajánlja, ezért ez az oldal azt tanítja. A Vue 2 életciklusa 2023. december 31-én véget ért.

Options API

A Vue 3-ban is működik, csak más stílus. Ha Composition API-ra írod át:

  • Régi: data() { return { darab: 0 } } Ma: const darab = ref(0)
  • Régi: methods: { novel() { this.darab++ } } Ma: function novel() { darab.value++ }

    Nincs this.

  • Régi: computed: { dupla() { return this.darab * 2 } } Ma: const dupla = computed(() => darab.value * 2)
  • Régi: watch: { kereses(uj) { mentes(uj) } } Ma: watch(kereses, uj => mentes(uj))
  • Régi: mounted() { this.betolt() } Ma: onMounted(() => betolt())
  • Régi: props: ['szoveg'] Ma: defineProps(['szoveg'])
  • Régi: this.$emit('torles') Ma: const emit = defineEmits(['torles']) emit('torles')
  • Régi: this.$refs.mezo Ma: useTemplateRef('mezo')

    Vue 3.5 óta.

  • Régi: components: { TeendoElem } Ma: import TeendoElem from './TeendoElem.vue'

    A <script setup>-ban az import elég.

Vue 2

Vue 3-ban már nem működik, ezt cserélni kell:

  • Régi: new Vue({ el: '#app' }) Ma: createApp(App).mount('#app')

    A Vue 3-ban megszűnt.

  • Régi: props: ['value'] + $emit('input') Ma: const ertek = defineModel()

    Vue 3-ban modelValue és update:modelValue.

  • Régi: this.$set(urlap, 'kesz', true) Ma: urlap.kesz = true

    A Vue 3 minden új mezőt figyel.

  • Régi: {{ ar | penznem }} Ma: {{ penznem(ar) }}

    A szűrők megszűntek, sima függvényt hívj.

  • Régi: Vue.component('TeendoElem', { … }) Ma: app.component('TeendoElem', TeendoElem)

    Vagy egyszerűen importáld, ahol kell.

Eszközök

Az eszközök is cserélődtek:

  • Régi: vue create teendolista Ma: npm create vue@latest

    A Vue CLI karbantartási módban van; az új projekt Vite-ra épül.

  • Régi: Vuex Ma: Pinia

    A Vuex karbantartási módban van; új projekthez a Pinia az ajánlott.

  • Régi: Vetur (VS Code) Ma: Vue - Official (VS Code)

    Vue 3-as projektben a Vetur legyen kikapcsolva.

Tovább

A hivatalos következő lépések. Mindegyik a npm create vue@latest varázslójában is kérhető, vagy később hozzáadható.

Források

Fogalmak és ajánlott minták: a Vue.js hivatalos dokumentációja alapján, saját megfogalmazásban és saját példákkal: vuejs.org/guide (új lapon nyílik) (Yuxi (Evan) You és a dokumentáció közreműködői, CC BY 4.0 (új lapon nyílik)).

Konzolüzenetek: szó szerint a vue 3.5.43 forrásából (@vue/runtime-core, @vue/reactivity, @vue/compiler-core, @vue/compiler-sfc), github.com/vuejs/core (új lapon nyílik), MIT-licenc; az ESLint-üzenet az eslint-plugin-vue 10.11.1-ből, MIT-licenc.

Verziók: az npm-tárház adatai (vue 3.5.43, 2026. szeptember 17.; a 3.6 ekkor még kiadásra jelölt), a Node-igény a create-vue 3.24.0 csomagból, a Vue 2 életciklusának vége a v2.vuejs.org/eol (új lapon nyílik) oldalról. Ellenőrizve: 2026. október 12.

A Vue.js a jogosultja védjegye; az oldal nem áll kapcsolatban vele. A kereső és a másolás a böngésződben fut, az oldal semmit nem ment és nem küld el.

Reaktív

Olyan adat, amelyet a Vue figyel. Ha megváltozik, a Vue magától frissíti az oldalon azokat a helyeket, ahol használod.

SFC (egyfájlos komponens)

Single-File Component: egy .vue fájl, amelyben a komponens HTML-je, JS-e és CSS-e együtt van.

Direktíva

A Vue saját attribútuma, v- előtaggal (vagy rövidítve :, @, #). Megmondja, mit csináljon a Vue az elemmel.

Kifejezés

JavaScript, aminek értéke van: 2 + 3, nev.toUpperCase(), kesz ? 'igen' : 'nem'. Az if, a let és a for utasítás, nem kifejezés.

Vite

Fejlesztőeszköz: helyi szervert indít, a mentett változást azonnal megmutatja a böngészőben, és a kész oldalt is ez építi (npm run build).

Node.js

JavaScript-futtató a böngészőn kívül. A Vue fejlesztőeszközei (npm, Vite) ezen futnak; a kész oldalhoz nem kell.

Komponens

Önálló, újrahasználható darab az oldalból, saját sablonnal, logikával és stílussal. Mintha saját HTML-elemet írnál.

Mellékhatás

Olyan művelet, ami nem csak értéket számol: mentés, szerverhívás, konzolra írás, a címsor átírása.

Életciklus

A komponens élete: létrejön, megjelenik az oldalon (onMounted), frissül (onUpdated), eltűnik (onUnmounted). Ezekhez a pontokhoz köthetsz kódot.

Composable

Újrahasznosítható függvény, amely Vue-s reaktivitást (ref, watch, horgok) használ. A neve use-zal kezdődik.

Menü

Vissza a főoldalra
Esc

↑↓ választás Enter megnyitás