本文介绍如何从零开始使用 Vue 3(前端) 与 Nest.js(后端) 构建一个现代全栈项目,并总结在开发、部署、接口设计、跨域和调试中的关键注意事项。
一、项目结构规划
在开始前,先确定项目的总体结构:
project-root/
│
├── frontend/ # Vue3 前端项目
│ ├── src/
│ ├── vite.config.js
│ └── package.json
│
├── backend/ # Nest.js 后端项目
│ ├── src/
│ ├── main.ts
│ └── package.json
│
└── README.md
这样前后端完全独立,开发调试更灵活,部署时也可以分开或整合。
二、创建 Vue3 前端项目
1 创建项目
npm create vite@latest frontend --template vue
cd frontend
npm install
建议使用 Vite 作为构建工具,启动速度快,热更新体验好。
2 使用 Composition API
在 Vue3 中推荐使用组合式 API:
<script setup>
import { ref } from 'vue'
const message = ref('Hello Vue3 + Nest!')
</script>
<template>
<h1>{{ message }}</h1>
</template>
3 配置接口代理(解决跨域)
在 vite.config.js 中添加代理配置:
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://localhost:5000',
changeOrigin: true,
},
},
},
})
这样前端请求
/api/...会自动代理到后端的localhost:5000。
三、创建 Nest.js 后端项目
1 创建项目
npm i -g @nestjs/cli
nest new backend
cd backend
npm run start:dev
2 创建控制器与服务
Nest 使用 装饰器(decorators) 管理模块、控制器、服务等。
// src/app.controller.ts
import { Controller, Get } from '@nestjs/common';
@Controller('api')
export class AppController {
@Get('hello')
getHello() {
return { message: 'Hello from Nest.js!' };
}
}
@Controller()定义路由前缀,@Get()定义 HTTP GET 接口。
3 运行测试接口
运行:
npm run start:dev
访问:
http://localhost:5000/api/hello
可以看到返回:
{ "message": "Hello from Nest.js!" }
四、前后端联调
前端发请求示例:
// frontend/src/api/index.js
import axios from 'axios';
export const getHello = () => {
return axios.get('/api/hello');
};
在组件中使用:
<script setup>
import { onMounted, ref } from 'vue'
import { getHello } from './api'
const message = ref('')
onMounted(async () => {
const res = await getHello()
message.value = res.data.message
})
</script>
五、跨域问题(CORS)配置
Vue 代理只在开发阶段有效。生产部署后,必须在 Nest.js 中配置 CORS。
在 main.ts 中:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors({
origin: ['http://localhost:5173'], // Vue3 项目地址
credentials: true,
});
await app.listen(5000);
}
bootstrap();
六、接口规范与模块化
Nest.js 最推荐的架构思路是 模块化设计:
nest g module user
nest g controller user
nest g service user
生成后自动结构:
src/
├── user/
│ ├── user.module.ts
│ ├── user.controller.ts
│ └── user.service.ts
例如:
// user.controller.ts
@Controller('api/user')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
getAll() {
return this.userService.findAll();
}
}
七、环境变量与端口管理
在 Nest 中使用 .env:
PORT=5000 DATABASE_URL=mysql://root:1234@localhost:3306/test
在 main.ts 中:
await app.listen(process.env.PORT || 5000);
Vue3 使用:
VITE_BASE_URL=http://localhost:5000
在前端访问:
import.meta.env.VITE_BASE_URL
八、部署注意事项
| 场景 | 方案 |
|---|---|
| 本地开发 | Vue 和 Nest 各自运行,端口不同 |
| 生产环境 | 构建 Vue (npm run build),然后由 Nginx 或 Nest 静态托管前端 |
| 后端接口 | 注意 .env 和跨域配置 |
| 构建后 | Vue 的接口地址要改为真实服务器 IP 或反向代理地址 |
九、常见坑点
-
跨域问题(CORS)
-
本地可通过代理解决;
-
线上必须用
enableCors()或 Nginx 配置。
-
-
接口路径不一致
- 确保 Vue 调用的路径(如
/api/...)与 Nest 的@Controller('api')对应。
- 确保 Vue 调用的路径(如
-
TypeORM 模块错误
-
需安装
npm i typeorm @nestjs/typeorm mysql2; -
配置时注意实体路径是否正确。
-
-
生产环境端口冲突
-
Nest 默认 3000,Vue 默认 5173;
-
修改 Nest 的
.env端口避免冲突。
-