先搭骨架:
app/
├── app.vue
├── layouts/
│ └── default.vue
├── pages/
│ ├── index.vue
│ └── news/
│ └── [slug].vue
├── composables/
│ └── useNewsList.ts
└── plugins/
└── station.ts
server/
└── api/
├── news.ts
└── news/
└── [slug].ts服务端接口:
// server/api/news.ts
export default defineEventHandler(() => {
return [
{ id: 1, slug: 'nuxt-4', title: 'Nuxt 4 继续进化' },
{ id: 2, slug: 'nitro-edge', title: 'Nitro 的边缘部署能力' }
]
})// server/api/news/[slug].ts
export default defineEventHandler((event) => {
const slug = getRouterParam(event, 'slug')
return {
slug,
title: `新闻详情:${slug}`,
content: `这是 ${slug} 的正文`
}
})组合式逻辑:
// app/composables/useNewsList.ts
export const useNewsList = () => {
return useFetch('/api/news', {
key: 'news-list'
})
}列表页:
<!-- app/pages/index.vue -->
<script setup lang="ts">
useHead({
title: '软件城市电视台首页'
})
const { data: news } = await useNewsList()
</script>
<template>
<section>
<h1>今晚新闻列表</h1>
<ul>
<li v-for="item in news" :key="item.id">
<NuxtLink :to="`/news/${item.slug}`">
{{ item.title }}
</NuxtLink>
</li>
</ul>
</section>
</template>详情页:
<!-- app/pages/news/[slug].vue -->
<script setup lang="ts">
const route = useRoute()
const { data: article } = await useFetch(`/api/news/${route.params.slug}`, {
key: `news:${route.params.slug}`
})
useHead({
title: article.value?.title ?? '新闻详情'
})
</script>
<template>
<article v-if="article">
<h1>{{ article.title }}</h1>
<p>{{ article.content }}</p>
</article>
</template>这套链路串起来就是:
pages 负责节目单
layout 负责舞美
server/api 负责后台供稿
useFetch 负责首屏取稿
useHead 负责导视
NuxtLink 负责栏目切换这时你才真正拥有了一套“会播出的 Vue 应用”。