Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 第四部分:实践与案例

第四部分:实践与案例

第10章:完整项目开发

实现一个完整的 MVVM 项目(例如:个人财务管理应用)

1. 项目概述

我们将开发一个个人财务管理应用,核心功能包括:

  • 收支记录增删改查
  • 按类别/时间统计报表
  • 预算设置与超支预警
  • 数据本地持久化(支持iCloud同步)

2. 架构设计

graph TD
    A[View] -->|绑定| B(ViewModel)
    B -->|读写| C[Model]
    C -->|通知| B
    B -->|驱动| A

3. 分层实现

Model 层设计

// 核心数据模型
struct Transaction: Identifiable, Codable {
    let id: UUID
    var amount: Double
    var category: Category
    var date: Date
    var notes: String
}

enum TransactionType: String, CaseIterable {
    case income, expense
}

// 持久化服务协议
protocol DataServiceProtocol {
    func save(_ transaction: Transaction) async throws
    func fetchAll() async throws -> [Transaction]
}

ViewModel 层实现

@MainActor
final class FinanceViewModel: ObservableObject {
    @Published private(set) var transactions: [Transaction] = []
    @Published var currentMonthTotal: Double = 0
    
    private let dataService: DataServiceProtocol
    
    init(dataService: DataServiceProtocol) {
        self.dataService = dataService
    }
    
    func addTransaction(_ transaction: Transaction) async {
        do {
            try await dataService.save(transaction)
            try await loadTransactions()
            calculateTotals()
        } catch {
            // 错误处理
        }
    }
    
    private func loadTransactions() async throws {
        transactions = try await dataService.fetchAll()
    }
}

View 层关键组件

struct TransactionListView: View {
    @StateObject var viewModel: FinanceViewModel
    
    var body: some View {
        List {
            Section("本月汇总") {
                AmountSummaryView(total: viewModel.currentMonthTotal)
            }
            
            ForEach(viewModel.transactions) { transaction in
                TransactionRow(transaction: transaction)
            }
            .onDelete(perform: deleteTransactions)
        }
        .task { await viewModel.loadTransactions() }
    }
    
    private func deleteTransactions(at offsets: IndexSet) {
        // 删除逻辑实现
    }
}

4. 关键技术实现

数据绑定示例

// 预算进度条组件
struct BudgetProgressView: View {
    @Binding var currentSpending: Double
    var budgetLimit: Double
    
    var body: some View {
        VStack {
            ProgressView(value: currentSpending, total: budgetLimit)
            Text("\(currentSpending.formatted(.currency(code: "CNY"))) / \(budgetLimit.formatted(.currency(code: "CNY")))")
        }
    }
}

跨组件通信

// 使用EnvironmentObject传递根ViewModel
@main
struct FinanceApp: App {
    @StateObject private var rootVM = AppRootViewModel()
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(rootVM)
        }
    }
}

5. 项目结构组织

FinanceApp/
├── Models/
│   ├── Transaction.swift
│   └── Category.swift
├── Services/
│   ├── DataService.swift
│   └── CloudKitService.swift
├── ViewModels/
│   ├── FinanceViewModel.swift
│   └── ReportViewModel.swift
├── Views/
│   ├── Transaction/
│   └── Dashboard/
└── Utilities/
    ├── Extensions/
    └── Formatters/

6. 典型问题解决方案

问题1:列表性能优化

// 使用LazyVStack替代List
ScrollView {
    LazyVStack(pinnedViews: .sectionHeaders) {
        ForEach(viewModel.transactions) { transaction in
            TransactionRow(transaction: transaction)
                .transactionListItemStyle() // 自定义样式修饰符
        }
    }
}

问题2:ViewModel 生命周期管理

// 使用@StateObject确保单例
struct CategoryView: View {
    @StateObject var viewModel = CategoryViewModel()
    
    var body: some View {
        // ...
    }
}

7. 完整功能流程图

sequenceDiagram
    participant User
    participant View
    participant ViewModel
    participant Model
    
    User->>View: 点击"添加支出"
    View->>ViewModel: addTransaction()
    ViewModel->>Model: save(data)
    Model-->>ViewModel: 保存结果
    ViewModel->>ViewModel: 重新计算统计
    ViewModel-->>View: 更新@Published属性
    View->>View: 自动刷新UI

8. 扩展思考

  • 如何添加多设备同步功能?
  • 实现导出PDF报表的方案
  • 接入银行API自动导入交易记录
Last Updated:: 4/25/25, 8:30 PM