效果展示

说明:
- 首页页面 - 名字“张三”是Java后端接口数据
- 产品介绍页面 - 产品介绍UL列表是动态数据
观察开发工具

可以看到首页的用户名是在HTML里面的,说明是服务端渲染
观察上面动图:同一个浏览器窗口内部跳转
可以发现,只请求了一个doc,其他页面都是没有请求doc的,为啥呢?这是nuxt的另一个机制,对seo蜘蛛友好的同时对用户也友好(速度比常规网站快)。
环境说明
- Nuxt.js 4.1.2
- 使用nuxt.js pages 模式
- node 20
- pnpm
项目创建
下载Nuxt官方starter项目,选中版本4.x即可 GitHub - nuxt/starter at v4
默认项目结构

Nuxtjs 项目编写
项目完整结构

提示:重点文件已经使用红色框住
项目配置 /nuxt.config.ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
compatibilityDate: '2025-07-15',
devtools: { enabled: true },
//启用服务器端渲染
ssr:true,
//启用pages模式
pages: true,
runtimeConfig: {
// 公共变量,客户端和服务端都可用
public: {
},
// runtimeConfig下,非[runtimeConfig.public]子节点变量均为私有变量,客户端不可用
apiKey: process.env.NUXT_API_KEY||'123456',
//process.env.NUXT_API_BASE_URL表示优先读取环境变量NUXT_API_BASE_URL,没有则使用默认值https://api.example.com
apiBaseURL: process.env.NUXT_API_BASE_URL || 'http://localhost:8080',
},
// 修改开发服务器端口
devServer: {
host: '0.0.0.0', // 可选 0.0.0.0 | 标识所有都可以访问
port: 3000 // 修改端口
},
//组件 禁用自动装配
// components: [
// {
// path: '~/components',
// pathPrefix: false,
// },
// ],
//自定义打包输出目录,默认.output 修改为output
nitro: {
output: {
dir: './output'
}
},
})
私有服务代理
私有服务代理,解决web前端直接访问Java服务端(或其他后端)由Nuxt代理访问,增加安全性。
/server/api/[...path].ts
为啥是/server这个目录,请参考nuxtjs4官方文档:server · Nuxt Directory Structure v4
![]()
其他目录定义也可以在这里找到
页面及导航组件
/app/components/webNav.vue
<script setup lang="ts">
</script>
<template>
<nav>
<NuxtLink to="/">
首页
</NuxtLink>
<span style="margin: 0 10px">|</span>
<NuxtLink to="/product/list">
产品介绍
</NuxtLink>
<span style="margin: 0 10px">|</span>
<NuxtLink to="/about.html">
关于我们
</NuxtLink>
</nav>
</template>
<style scoped>
</style>
/app/app.vue
<template>
<div>
<NuxtPage />
</div>
</template>
/app/error.vue
<script setup lang="ts">
import type { NuxtError } from '#app'
const props = defineProps({
error: Object as () => NuxtError
})
</script>
<template>
<div>
<h1>错误码:{{ error.statusCode }}</h1>
<NuxtLink to="/">返回首页</NuxtLink>
</div>
</template>
/app/pages/index.vue
<template>
<h1>首页</h1>
<web-nav/>
<article>
<h2>你好[{{userName}}],欢迎来到首页</h2>
</article>
</template>
<script setup lang="ts">
import webNav from '~/components/webNav.vue';
const {data:userName} = await useAsyncData('user-name',async ()=>{
try {
const {data} = await $fetch('/api/nuxt/getName',{
method:'POST',
})
console.log('获取用户名成功:',data)
return data;
}catch (err){
console.error('Failed to load userName:', err)
return '--'
}
})
</script>
/app/pages/about.vue
<script setup lang="ts">
import WebNav from "../components/webNav.vue";
</script>
<template>
<h1>关于我们</h1>
<web-nav/>
<article>
<h2>欢迎来到关于我们页面</h2>
</article>
</template>
<style scoped>
</style>
/app/pages/product/list.vue
<template>
<h1>产品介绍</h1>
<web-nav/>
<article>
<h2>欢迎来到产品介绍</h2>
<p>
这里是产品介绍页面
</p>
<ul >
<li v-for="item in products">{{ item }}</li>
</ul>
</article>
</template>
<script setup lang="ts">
import WebNav from "../../components/webNav.vue";
const {data:products} = await useAsyncData('products',async ()=>{
try {
const {data} = await $fetch('/api/nuxt/product/list',{
method:'POST',
})
console.log('获取产品成功:',data)
return data;
}catch (err){
console.error('Failed to load products:', err)
return []
}
})
</script>
项目启动和构建
启动项目
在项目根目录打开终端或打开终端切换到项目根目录
安装依赖
pnpm install
启动项目
pnpm dev
构建项目
pnpm build
其他工具可参考项目的REAMD.MD
文档
项目部署
docker 方案
docker-compose.yml配置
version: "3.8"
networks:
nuxtRouter:
services:
nuxt-web:
image: node:20.19.5-alpine
container_name: nuxt-web
hostname: nuxt-web
restart: always
# ports:
# - 3080:3080
networks:
- nuxtRouter
volumes:
- ./output:/app/output
working_dir: /app
command: ["node","output/server/index.mjs"]
environment:
- NITRO_PORT=3000
deploy:
resources:
limits:
memory: 512M
healthcheck:
test: ["CMD","curl","-f","http://127.0.0.1:3080"]
interval: 30s
timeout: 5s
retries: 5
start_period: 30s
- 将打包好的output文件夹映射到容器的
/app/output
目录 working_dir
设置为/app- 容器执行启动命令
["node","output/server/index.mjs"]
特别注意路径
启动
docker-compose up -d
查看日志
docker-compose logs -f
重启
docker-compose restart
停止
docker-compose down
https://blog.xqlee.com/article/2510151406166550.html
评论