npx nuxi init my-app | 새 프로젝트 생성 |
npm run dev | 개발 서버 시작 |
npm run build | 프로덕션 빌드 |
npm run preview | 프로덕션 미리보기 |
npm run generate | 정적 생성 |
npx nuxi add page about | 페이지 추가 |
npx nuxi add component MyButton | 컴포넌트 추가 |
npx nuxi add composable useCounter | composable 추가 |
pages/
├── index.vue # /
├── about.vue # /about
├── users/
│ ├── index.vue # /users
│ └── [id].vue # /users/:id
├── [...slug].vue # Catch-all route
└── [[optional]].vue # Optional param <template>
<!-- NuxtLink component -->
<NuxtLink to="/">Home</NuxtLink>
<NuxtLink :to="{ name: 'users-id', params: { id: 1 }}">User 1</NuxtLink>
<!-- Programmatic navigation -->
<button @click="navigateTo('/about')">About</button>
</template>
<script setup>
// Get route params
const route = useRoute()
console.log(route.params.id)
// Navigate
await navigateTo('/about')
await navigateTo({ path: '/users', query: { page: 1 }})
</script> <script setup>
// useFetch - for API calls
const { data, pending, error, refresh } = await useFetch('/api/users')
// With options
const { data: user } = await useFetch(`/api/users/${id}`, {
key: `user-${id}`,
pick: ['name', 'email'],
transform: (data) => data.user,
watch: [id]
})
// useAsyncData - for custom async operations
const { data } = await useAsyncData('users', async () => {
const [users, posts] = await Promise.all([
$fetch('/api/users'),
$fetch('/api/posts')
])
return { users, posts }
})
// Lazy loading (don't block navigation)
const { data, pending } = await useLazyFetch('/api/data')
</script> // composables/useCounter.ts
export const useCounter = () => {
const count = useState('counter', () => 0)
const increment = () => count.value++
const decrement = () => count.value--
return { count, increment, decrement }
}
// Usage in component
<script setup>
const { count, increment } = useCounter()
</script> // stores/user.ts
export const useUserStore = defineStore('user', {
state: () => ({
user: null as User | null,
isLoggedIn: false
}),
getters: {
fullName: (state) => `${state.user?.firstName} ${state.user?.lastName}`
},
actions: {
async login(email: string, password: string) {
this.user = await $fetch('/api/login', {
method: 'POST',
body: { email, password }
})
this.isLoggedIn = true
}
}
})
// Usage
const userStore = useUserStore()
await userStore.login(email, password) // server/api/users.ts
export default defineEventHandler(async (event) => {
return { users: [{ id: 1, name: 'John' }] }
})
// server/api/users/[id].ts
export default defineEventHandler(async (event) => {
const id = getRouterParam(event, 'id')
return { id, name: 'John' }
})
// server/api/users.post.ts
export default defineEventHandler(async (event) => {
const body = await readBody(event)
return { created: body }
})
// Query params
const query = getQuery(event)
// Headers
const token = getHeader(event, 'authorization') // server/middleware/auth.ts
export default defineEventHandler((event) => {
const token = getHeader(event, 'authorization')
if (!token) {
throw createError({
statusCode: 401,
message: 'Unauthorized'
})
}
// Add user to context
event.context.user = verifyToken(token)
}) export default defineNuxtConfig({
devtools: { enabled: true },
modules: [
'@nuxtjs/tailwindcss',
'@pinia/nuxt'
],
runtimeConfig: {
apiSecret: '', // Server only
public: {
apiBase: '' // Exposed to client
}
},
app: {
head: {
title: 'My App',
meta: [
{ name: 'description', content: 'My Nuxt app' }
]
}
},
css: ['~/assets/css/main.css'],
nitro: {
preset: 'cloudflare-pages'
}
})