你瞅啥呢

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 的组件注册和插件配置
posted @ 2025-11-27 14:43  叶乘风  阅读(4)  评论(0)    收藏  举报