2025-11-27 用前端vue的架构来类比 NestJS 的各个部分(deepseek)
用 前端Vue的架构来类比 NestJS 的各个部分:
1. DTO (Data Transfer Object) - Vue 中的 Props/表单验证规则
Vue 中的 Props 定义:
// Vue 组件 Props
export interface UserFormProps {
username: string;
email: string;
password: string;
role?: 'user' | 'admin';
}
// 或者使用表单验证
const rules = {
username: [
{ required: true, message: '用户名不能为空' },
{ min: 3, max: 20, message: '用户名长度3-20字符' },
{ pattern: /^[a-zA-Z0-9_]+$/, message: '只能字母数字下划线' }
],
email: [
{ required: true, message: '邮箱不能为空' },
{ type: 'email', message: '邮箱格式不正确' }
]
}
NestJS DTO 对应:
// NestJS DTO
export class CreateUserDto {
@IsNotEmpty({ message: '用户名不能为空' })
@IsString()
@MinLength(3)
@MaxLength(20)
@Matches(/^[a-zA-Z0-9_]+$/, { message: '只能字母数字下划线' })
username: string;
@IsNotEmpty()
@IsEmail()
email: string;
@IsNotEmpty()
@MinLength(6)
password: string;
@IsOptional()
@IsEnum(['user', 'admin'])
role?: string;
}
类比:DTO 就像 Vue 组件的 Props 接口定义 + 表单验证规则
2. Controller - Vue 中的页面组件/路由组件
Vue 页面组件:
<!-- Vue 页面组件 -->
<template>
<div class="user-page">
<!-- 用户列表 -->
<user-list :users="users" @edit="handleEdit" @delete="handleDelete" />
<!-- 搜索框 -->
<search-bar @search="handleSearch" />
<!-- 分页 -->
<pagination :current="page" :total="total" @change="handlePageChange" />
</div>
</template>
<script setup>
// 相当于 Controller 的方法
const handleSearch = async (keyword) => {
loading.value = true
try {
const response = await userApi.searchUsers(keyword)
users.value = response.data
} catch (error) {
message.error('搜索失败')
} finally {
loading.value = false
}
}
const handleEdit = (user) => {
router.push(`/user/edit/${user.id}`)
}
const handleDelete = async (userId) => {
await userApi.deleteUser(userId)
message.success('删除成功')
loadUserList()
}
</script>
NestJS Controller 对应:
// NestJS Controller
@Controller('users')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
async getUsers(@Query() query: UserQueryDto) {
// 相当于 Vue 中的 handleSearch
return this.userService.findAll(query)
}
@Patch(':id')
async updateUser(
@Param('id') id: string,
@Body() updateUserDto: UpdateUserDto
) {
// 相当于 Vue 中的 handleEdit
return this.userService.update(+id, updateUserDto)
}
@Delete(':id')
async deleteUser(@Param('id') id: string) {
// 相当于 Vue 中的 handleDelete
await this.userService.remove(+id)
return { message: '删除成功' }
}
}
类比:Controller 就像 Vue 的页面组件,负责接收请求、调用服务、返回响应
3. Service - Vue 中的 Composables/Store Actions
Vue Composables (类似 Vue 3 的 useXxx):
// Vue Composable - 用户相关业务逻辑
export const useUser = () => {
const users = ref<User[]>([])
const loading = ref(false)
// 获取用户列表
const fetchUsers = async (params?: any) => {
loading.value = true
try {
const response = await api.get('/users', { params })
users.value = response.data
return response.data
} finally {
loading.value = false
}
}
// 创建用户
const createUser = async (userData: CreateUserData) => {
const response = await api.post('/users', userData)
users.value.push(response.data)
return response.data
}
// 更新用户
const updateUser = async (id: number, userData: UpdateUserData) => {
const response = await api.patch(`/users/${id}`, userData)
const index = users.value.findIndex(user => user.id === id)
if (index !== -1) {
users.value[index] = response.data
}
return response.data
}
return {
users,
loading,
fetchUsers,
createUser,
updateUser
}
}
或者 Vuex/Pinia Store:
// Pinia Store
export const useUserStore = defineStore('user', {
state: () => ({
users: [],
currentUser: null
}),
actions: {
// 相当于 Service 的方法
async loadUsers(params) {
const response = await userApi.getUserList(params)
this.users = response.data
},
async createUser(userData) {
const response = await userApi.createUser(userData)
this.users.push(response.data)
},
async updateUser(id, userData) {
const response = await userApi.updateUser(id, userData)
const index = this.users.findIndex(user => user.id === id)
if (index !== -1) {
this.users[index] = response.data
}
}
}
})
NestJS Service 对应:
// NestJS Service
@Injectable()
export class UserService {
constructor(
@InjectRepository(User)
private userRepository: Repository<User>
) {}
// 相当于 Composables 中的 fetchUsers
async findAll(params: UserQueryDto) {
const { page, limit, search } = params
const query = this.userRepository.createQueryBuilder('user')
if (search) {
query.where('user.username LIKE :search', { search: `%${search}%` })
}
const [users, total] = await query
.skip((page - 1) * limit)
.take(limit)
.getManyAndCount()
return { users, total, page, limit }
}
// 相当于 Composables 中的 createUser
async create(createUserDto: CreateUserDto) {
const user = this.userRepository.create(createUserDto)
return await this.userRepository.save(user)
}
// 相当于 Composables 中的 updateUser
async update(id: number, updateUserDto: UpdateUserDto) {
await this.userRepository.update(id, updateUserDto)
return this.userRepository.findOne({ where: { id } })
}
}
类比:Service 就像 Vue 的 Composables 或 Store Actions,包含核心业务逻辑
4. Module - Vue 中的组件注册/插件安装
Vue 中的全局组件注册:
// main.ts - 全局组件注册
import UserList from '@/components/UserList.vue'
import UserForm from '@/components/UserForm.vue'
const app = createApp(App)
app.component('UserList', UserList)
app.component('UserForm', UserForm)
Vue 中的插件安装:
// 安装路由、状态管理、UI库
app.use(router)
app.use(pinia)
app.use(ArcoVue)
NestJS Module 对应:
// NestJS Module
@Module({
imports: [
TypeOrmModule.forFeature([User]), // 相当于注册数据库相关
AuthModule, // 相当于安装认证插件
ConfigModule // 相当于安装配置插件
],
controllers: [UserController], // 相当于注册页面组件
providers: [UserService], // 相当于注册业务逻辑
exports: [UserService] // 相当于导出供其他模块使用
})
export class UserModule {}
类比:Module 就像 Vue 应用中的组件注册和插件安装配置
5. 完整对比示例
Vue 项目结构:
src/
├── components/ # 可复用组件
│ ├── UserList.vue # 用户列表组件
│ └── UserForm.vue # 用户表单组件
├── views/ # 页面组件 (类似 Controller)
│ ├── UserManagement.vue
│ └── UserDetail.vue
├── composables/ # 业务逻辑 (类似 Service)
│ └── useUser.ts
├── stores/ # 状态管理
│ └── user.ts
└── types/ # 类型定义 (类似 DTO)
└── user.ts
NestJS 项目结构:
src/
├── modules/
│ └── user/
│ ├── user.module.ts # 模块配置
│ ├── user.controller.ts # 控制器 (类似 Views)
│ ├── user.service.ts # 服务 (类似 Composables/Stores)
│ ├── dto/ # 数据传输对象 (类似 Props/表单规则)
│ │ ├── create-user.dto.ts
│ │ └── update-user.dto.ts
│ └── entities/ # 实体类 (类似 Types)
│ └── user.entity.ts
6. 数据流向对比
Vue 前端数据流:
用户操作 → 页面组件 → Composables/Store → API 调用 → 后端
用户输入 → 表单验证 → 业务处理 → 状态更新 → 界面刷新
NestJS 后端数据流:
HTTP 请求 → Controller → Service → 数据库操作 → 返回响应
请求数据 → DTO 验证 → 业务逻辑 → 数据持久化 → JSON 响应
总结:
- DTO = Vue 的 Props 接口 + 表单验证规则
- Controller = Vue 的页面组件(处理用户交互)
- Service = Vue 的 Composables/Store Actions(业务逻辑)
- Module = Vue 的组件注册和插件配置

浙公网安备 33010602011771号