07 β Nuxt asoslari¶
β¬ οΈ Oldingi: 06 β Pinia Β· π README Β· Keyingi: 08 β Data & Server β‘οΈ
Vue β kutubxona/freymvork. Nuxt β Vue ustiga qurilgan meta-framework: routing, SSR, server API, auto-import, SEO β hammasini "convention" bilan tayyor beradi.
Eng aniq analogiya: Vue β React kabi, Nuxt β Laravel kabi. Sen Laravel'da har safar router, ORM, middleware'ni noldan yozmaysan β convention bor. Nuxt ham xuddi shunday: papkaga fayl tashlaysan, route o'zi paydo bo'ladi.
Nuxt nima beradi (Vue'da o'zing qilishing kerak bo'lganini)¶
- File-based routing β
router/index.jsyozmaysan (05-modulni eslagin β endi avtomatik) - SSR/SSG β server'da render (SEO, tezlik)
- Auto-imports β
import { ref }yozmaysan; composable/komponentlar avtomatik - Server engine (Nitro) β
/api/...backend endpointlar shu loyihaning ichida - Layouts, middleware, plugins β Laravel'dagidek tuzilma
Bu modul Nuxt 4 strukturasiga asoslangan. Nuxt 3 farqlari belgilab ketiladi.
7.1 O'rnatish¶
Nuxt 4 papka strukturasi¶
my-nuxt-app/
βββ app/ # β brauzerga ketadigan HAMMA narsa shu yerda (Nuxt 4)
β βββ app.vue # ildiz komponent (Laravel layouts/app.blade.php kabi)
β βββ pages/ # routing β har fayl = route
β βββ components/ # auto-import komponentlar
β βββ composables/ # auto-import composable'lar
β βββ layouts/ # qayta ishlatiladigan sahifa qoliplari
β βββ middleware/ # route middleware (auth va h.k.)
β βββ plugins/ # ilova boot'ida ishlaydigan kod
β βββ assets/ # build qilinadigan CSS/rasm
β βββ utils/ # auto-import sof funksiyalar
βββ server/ # β Nitro backend (root'da qoladi)
β βββ api/ # /api/... endpointlar
β βββ ...
βββ shared/ # app + server BIRGA ishlatadigan kod (types, utils)
βββ public/ # to'g'ridan-to'g'ri xizmat (favicon, robots.txt)
βββ nuxt.config.ts # asosiy konfiguratsiya
βββ package.json
Nuxt 3 da farq:
app/papkasi yo'q edi βpages/,components/,composables/,app.vueto'g'ridan-to'g'ri ildizda turardi. Nuxt 4 ularniapp/ichiga ko'chirdi (toza ajratish + tezroq startup). Eski tuzilma hali ishlaydi (backward compat), lekin yangi loyihadaapp/ishlat.
Nega app/ va server/ ajratilgan? app/ β brauzer konteksti, server/ β Node/Nitro konteksti. Ikkisida turli global'lar, turli import'lar bor. Ajratish IDE type-safety va xatolarning oldini oladi. Backend dasturchi sifatida bu mantiq senga tushunarli β frontend va backend kodi aralashmasligi kerak.
7.2 app.vue β ildiz komponent¶
Eng minimal Nuxt ilovasi β faqat app/app.vue:
Routing kerak bo'lsa β <NuxtPage /> qo'shasan (bu Vue Router'dagi <RouterView> ning Nuxt versiyasi):
<!-- app/app.vue -->
<template>
<div>
<AppHeader /> <!-- auto-import! import yozish shart emas -->
<NuxtPage /> <!-- joriy sahifa shu yerda render bo'ladi -->
<AppFooter />
</div>
</template>
app/pages/papkasi bo'lmasa, Nuxtvue-routerni umuman qo'shmaydi (faqat bittaapp.vueβ landing page uchun). Routing kerak bo'lgandapages/ochasan.
7.3 File-based routing β eng katta "wow"¶
app/pages/ ichidagi har fayl avtomatik route bo'ladi. router/index.js YO'Q.
app/pages/
βββ index.vue β /
βββ about.vue β /about
βββ contact.vue β /contact
βββ blog/
β βββ index.vue β /blog
β βββ [slug].vue β /blog/:slug (dynamic)
βββ users/
β βββ [id].vue β /users/:id
βββ [...slug].vue β 404 catch-all
05-modul bilan solishtir: o'sha yerda routes massivini qo'lda yozgansan. Nuxt'da β papka tuzilishi = route. Bu Laravel'ning php artisan route:list mantiqiga o'xshaydi: convention bor, qo'lda ro'yxat yo'q.
Quyidagi diagramma app/pages/ papkasidagi har bir fayl qanday qilib avtomatik URL route'iga aylanishini ko'rsatadi:
Dynamic route va parametr¶
<!-- app/pages/users/[id].vue β /users/123 -->
<script setup>
const route = useRoute() // auto-import β vue-router'dan import yo'q
const id = route.params.id
</script>
<template>
<h1>User #{{ id }}</h1>
</template>
Navigatsiya β <NuxtLink>¶
<template>
<nav>
<NuxtLink to="/">Bosh</NuxtLink>
<NuxtLink to="/about">Haqida</NuxtLink>
<NuxtLink :to="`/users/${user.id}`">{{ user.name }}</NuxtLink>
</nav>
</template>
<NuxtLink> β <RouterLink> ning aqlli versiyasi: prefetch (ko'rinishga kirganda sahifani oldindan yuklaydi), tashqi linklarni avtomatik aniqlaydi. Dasturiy navigatsiya: navigateTo('/about') (auto-import).
Nested routes¶
app/pages/dashboard.vue + app/pages/dashboard/ papka:
app/pages/
βββ dashboard.vue β ota (ichida <NuxtPage/> bo'lishi kerak)
βββ dashboard/
βββ index.vue β /dashboard
βββ profile.vue β /dashboard/profile
βββ settings.vue β /dashboard/settings
<!-- app/pages/dashboard.vue -->
<template>
<div>
<aside>Yon menyu (doim qoladi)</aside>
<NuxtPage /> <!-- bola sahifa shu yerda -->
</div>
</template>
7.4 Layouts β qayta ishlatiladigan qoliplar¶
Bir nechta sahifa bir xil ramkani (header/footer/sidebar) baham ko'rsa β layout. Laravel @extends('layouts.app') ning aynan o'zi.
<!-- app/layouts/default.vue -->
<template>
<div>
<AppHeader />
<main>
<slot /> <!-- sahifa kontenti shu yerga tushadi -->
</main>
<AppFooter />
</div>
</template>
<!-- app/layouts/admin.vue -->
<template>
<div class="admin">
<AdminSidebar />
<slot />
</div>
</template>
Sahifada layout tanlash:
<!-- app/pages/admin/index.vue -->
<script setup>
definePageMeta({ layout: 'admin' }) // default'dan boshqa
</script>
app/app.vue da <NuxtLayout> bo'lishi kerak (yoki Nuxt avtomatik o'raydi):
default.vue nomli layout β avtomatik standart. Boshqasini xohlasang definePageMeta({ layout: 'admin' }).
Diagrammada layout doimiy ramka bo'lib qolishi va <slot /> ichiga har bir sahifa kontenti tushishi tasvirlangan:
7.5 Auto-imports β "import yo'q" sehri¶
Nuxt avtomatik import qiladi:
- Vue API: ref, computed, watch, onMounted β import yozma
- app/components/ β har komponent global ishlatishga tayyor
- app/composables/ β useX() avtomatik
- app/utils/ β sof funksiyalar avtomatik
- Nuxt composable'lari: useRoute, useRouter, useFetch, useState, navigateTo, ...
<script setup>
// HECH QANDAY import yo'q β hammasi avtomatik
const count = ref(0)
const route = useRoute()
const { data } = await useFetch('/api/users')
</script>
<template>
<MyButton @click="count++">Bosildi: {{ count }}</MyButton>
<!-- MyButton = app/components/MyButton.vue, import qilinmagan! -->
</template>
Komponent nomlash (nested)¶
app/components/
βββ AppHeader.vue β <AppHeader />
βββ base/
β βββ Button.vue β <BaseButton /> (papka + fayl nomi)
βββ user/
βββ Card.vue β <UserCard />
Nuxt papka nomini prefiks qiladi: base/Button.vue β <BaseButton>. Bu β komponentlarni guruhlash + nom to'qnashuvini oldini oladi.
Quyidagi diagramma Nuxt build paytida belgilangan papkalarni skanerlab, kerakli import'larni o'zi qanday qo'shishini ko'rsatadi:
Auto-import yoqdimi-yo'qmi? Ko'pchilik yoqtiradi (kam boilerplate). Aniq import xohlasang
nuxt.configda o'chirsa bo'ladi, lekin tavsiya β convention'ga ergash.
7.6 definePageMeta va useHead (SEO)¶
<script setup>
definePageMeta({
layout: 'admin',
middleware: 'auth', // app/middleware/auth.ts
title: 'Boshqaruv paneli',
})
// SEO/meta teglar
useHead({
title: 'EduCore β Boshqaruv',
meta: [
{ name: 'description', content: 'O\'quv markazi boshqaruv tizimi' },
],
})
// Yoki qulayroq:
useSeoMeta({
title: 'EduCore',
description: 'O\'quv markazlari uchun SaaS',
ogImage: '/og.png',
})
</script>
useSeoMeta/useHead β har sahifaga unikal SEO. SSR tufayli bu meta teglar server HTML'ida bo'ladi β Google/ijtimoiy tarmoq to'g'ri o'qiydi. (Oddiy Vue SPA'da bu muammo, Nuxt hal qiladi.)
7.7 nuxt.config.ts β markaziy konfiguratsiya¶
// nuxt.config.ts
export default defineNuxtConfig({
devtools: { enabled: true },
modules: [
'@pinia/nuxt',
'@nuxtjs/tailwindcss',
'@nuxt/image',
],
css: ['~/assets/css/main.css'],
runtimeConfig: {
apiSecret: '', // faqat server (maxfiy)
public: {
apiBase: 'https://api.educore.uz', // brauzerga ham ochiq
},
},
app: {
head: {
title: 'EduCore',
htmlAttrs: { lang: 'uz' },
},
},
})
~/yoki@/βapp/papkani bildiradi (Nuxt 4).runtimeConfigβ.envqiymatlarni xavfsiz boshqarish (apiSecretbrauzerga chiqmaydi,publicchiqadi). Laravel'dagiconfig()+.envajratimiga o'xshaydi.
7.8 Pinia'ni Nuxt'ga ulash¶
Endi app/stores/ dagi store'lar auto-import bo'ladi β createPinia() qo'lda kerak emas (06-moduldagi setup Nuxt qiladi). Store'larni xuddi 06-moduldagidek yozasan.
Xulosa¶
- Nuxt = "Vue uchun Laravel" β convention over configuration
- Nuxt 4: ilova kodi
app/da, backendserver/da, umumiy kodshared/da app/pages/= file-based routing ([id].vue= dynamic,[...slug].vue= catch-all) β qo'lda router yo'q<NuxtPage>(= RouterView),<NuxtLink>(= aqlli RouterLink, prefetch),navigateTo()- Layouts (
app/layouts/) = Blade@extends;<slot/>ga sahifa tushadi - Auto-imports: Vue API, komponent, composable, util β import yozmaysan
definePageMeta(layout/middleware),useSeoMeta/useHead(SSR SEO)nuxt.config.ts+runtimeConfig(maxfiy/public ajratish)
π― Masalalar (kamida 20 ta)¶
Setup & routing (1β8)¶
nuxi initbilan loyiha yarat, ishga tushir,app/app.vueni o'zgartirib brauzerda ko'r.app/pages/index.vue,about.vue,contact.vueyarat;<NuxtLink>bilan nav qil.router/index.jsyo'qligiga e'tibor ber.- Dynamic route (β
):
app/pages/users/[id].vue;/users/5,/users/42ga kiribroute.params.idni ko'rsat. - Catch-all (β
):
app/pages/[...slug].vue404 sahifa yasa; mavjud bo'lmagan URL'ni ushla. <NuxtLink>prefetch (β ): Network tab'da, linkga hover qilganda sahifa oldindan yuklanishini kuzat.navigateTo(β ): tugma bosilganda dasturiy ravishda/aboutga o't.- Nested route (β
β
):
app/pages/dashboard.vue+dashboard/profile.vue,dashboard/settings.vue; yon menyu doim qolsin. - Blog (β
β
):
app/pages/blog/index.vue(ro'yxat) +blog/[slug].vue(post); ro'yxatdan postga<NuxtLink>bilan o't.
Layouts (9β12)¶
app/layouts/default.vue(header+footer+slot) yarat; barcha sahifalar undan foydalansin.app/layouts/admin.vue(β ) yarat;definePageMeta({ layout: 'admin' })bilan faqat admin sahifalarga qo'lla.- Layout'siz sahifa (β
): Login sahifasiga
layout: falseyoki bo'sh layout ber. - Dinamik layout (β
β
): foydalanuvchi rolega qarab layout almashtirish (
definePageMeta+ computed/middleware).
Auto-import & komponentlar (13β17)¶
app/components/AppHeader.vueyarat; import qilmasdanapp.vueda ishlat.- Nested komponent (β
):
app/components/base/Button.vueβ<BaseButton>sifatida ishlat. - Composable auto-import (β
):
app/composables/useCounter.tsyarat (04-moduldan); import yozmasdan sahifada ishlat. - Util auto-import (β
):
app/utils/formatDate.tsyarat; sahifada to'g'ridan-to'g'ri chaqir. - 04-moduldagi
useToggleniapp/composables/ga ko'chir va modal komponentida ishlat.
Meta, config, integratsiya (18β24)¶
- SEO (β
): har sahifaga
useSeoMetabilan unikal title/description ber; View Source'da meta'lar HTML'da ekanini tasdiqla (SSR isboti). definePageMeta({ title })(β ):app/layoutsyoki plugin orqali sahifa title'ini boshqar.- TailwindCSS (β
):
@nuxtjs/tailwindcssmodulini ulab, sahifani Tailwind bilan stilla. - Pinia (β
β
):
@pinia/nuxtni ulab, 06-moduldagiuseCartStoreni Nuxt'da ishlat (auto-import store). runtimeConfig(β β ):public.apiBaseqo'sh; sahifadauseRuntimeConfig().public.apiBaseni o'qib ko'rsat.- 05β07 solishtiruv (β β ): 05-moduldagi qo'lda Vue Router setup'ini Nuxt file-based routing bilan taqqosla; xulosani izoh sifatida yoz (qaysi convention nimani avtomatlashtirdi).
- EduCore skeleti (β
β
β
):
app/pages/daindex,login,app/(dashboard, students, payments β nested),admin/;default+admin+authlayout'lar; auto-import header/sidebar komponentlari. (Middleware/auth β keyingi modulda to'liq.)
β Tanlangan yechimlar¶
7 β Nested dashboard
10 β Admin layout
β‘οΈ Keyingi: 08 β Data Fetching & Server (Nitro)