Files
DDDMicroFrontend/README.md
编码猿 02cae30c4c 333
2025-09-17 02:31:37 +08:00

6.3 KiB
Raw Blame History

DDD领域驱动设计的微服务前端案例

持续开发中及时拉取代码文档还不够完善先凑合看目前只是demo代码还会进行大规模封装细化和改造

搭建的一套基于DDD领域驱动设计的微服务前端,适用于大型企业,开发大型复杂且拓展灵活的前端应用的架构方案。

微服务架构中,前端用什么语言不受约束,随意就好!

项目大致技术栈:

开发任务

  • 基于DDD理念改造
  • 基于 vite-plugin-federation 拆分领域模块为联邦模块,实现微前端
  • 领域模块实现 docker自动化构建部署上线
  • Deno集成GraphQL

文件夹结构

根目录:

.
├── back-end          # 【后端】基于Deno写的后端 测试接口,仅供测试
├── doc               # 一些markdown笔记
├── front-end         # 前端 微服务 项目
│   ├── app-car       # 独立的【购物车】领域模块
│   ├── app-product   # 独立的【商品】领域模块
│   ├── ....          # 实际项目还会有更多其他的领域模块
│   └── main-app      # 主应用(入口应用)
└── README.md         # 帮助文档

main-app 目录:

src/
├── domains/                # 【核心】领域层 - 所有业务领域模块
│   └── product/            # 订单领域模块app-product
│       ├── domain/         # 领域模型(充血模型)
│       │   ├── entities/   # 实体Product, ProductLineItem
│       │   ├── value-objects/ # 值对象Money, Address
│       │   ├── types/      # 领域内通用类型
│       │   ├── enums/      # 领域枚举
│       │   └── events/     # 领域事件(如果需要)
│       ├── application/    # 应用服务层 - 协调领域对象完成用例
│       │   └── services/   # 应用服务ProductApplicationService
│       ├── infrastructure/ # 基础设施层 - 领域层的具体实现
│       │   └── api/        # 数据获取实现HttpProductRepository
│       ├── ports/          # 端口(接口/抽象类)- 定义契约
│       │   └── repositories/ # 仓储接口ProductRepository
│       └── use-cases/      # (可选)或将用例放在这里
├── app/                    # 【交付层】应用组装和配置路由、状态管理、主布局、UI库设置、错误处理、依赖注入容器
│   ├── components/         # 通用UI组件与业务无关如ButtonModal
│   ├── layouts/            # 布局组件
│   ├── di/                 # 依赖注入配置
│   ├── router/             # Vue Router 配置
│   ├── stores/             # Pinia Store用于UI状态管理非核心业务状态
│   └── main.ts             # 应用入口,依赖注入的组装之地
│   └── App.vue             # 根组件
├── features/               # 【交付层】基于领域的功能模块:关注具体的业务功能实现,它是舞台上的“演员”和“节目”。
│   └── product/            # 订单功能模块app-product
│       ├── components/     # 订单领域专用的UI组件
│       ├── views/          # 订单相关的页面级Vue组件
│       ├── router/          # 订单相关的页面级Vue组件
│       ├── composables/    # 订单相关的Vue组合式函数
│       └── index.ts        # 订单功能模块的出口
├── shared/                 # 共享资源
│   ├── infra(infrastructure) # 基础设施层
│   │   ├── http/  
│   ├── lib/                # 第三方库的封装/工具函数
│   ├── utils/              # 纯工具函数
│   └── types/              # 全局通用的TypeScript类型定义
│   └── constants/          # 全局常量(如错误码、正则)
│   └── exceptions/         # 通用异常如NotFoundError
└── public/                 # 静态资源目录
└── index.html              # 主HTML文件

问 & 答

问: 为什么vue项目要抛弃SFC写法而尝试jsx/tsx方式来编码 答:https://juejin.cn/post/6911175470255964174

问:不会 vue3 jsx 语法,怎么办? 答:https://juejin.cn/post/7141674726434439176

vue3 jsx defineComponent 语法,实际项目中 setup 代码太长,怎么办? 答:使用组合式函数 (Composables)

案例:

// composables/useUserData.js
import { ref, onMounted } from 'vue'
import api from '@/api'

export function useUserData(userId) {
  const user = ref(null)
  const loading = ref(false)
  const error = ref(null)

  const fetchUser = async () => {
    loading.value = true
    try {
      user.value = await api.getUser(userId)
    } catch (err) {
      error.value = err.message
    } finally {
      loading.value = false
    }
  }

  onMounted(fetchUser)

  return {
    user,
    loading,
    error,
    refetch: fetchUser
  }
}

主组件:

// UserProfile.jsx
import { defineComponent } from 'vue'
import { useUserData } from '@/composables/useUserData'

export default defineComponent({
  name: 'UserProfile',
  
  props: {
    userId: {
      type: String,
      required: true
    }
  },
  
  setup(props) {
    const { user, loading, error, refetch } = useUserData(props.userId)
    
    return () => (
      <div>
        {loading.value && <div>Loading...</div>}
        {error.value && <div>Error: {error.value}</div>}
        {user.value && (
          <div>
            <h2>{user.value.name}</h2>
            <p>{user.value.email}</p>
          </div>
        )}
      </div>
    )
  }
})