You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在SwiftUI中使用MVVM是否为不良实践?显式定义ViewModel是否冗余?

SwiftUI架构选择:MV还是MVVM?

核心结论

这不全是个人偏好问题,是否需要显式定义ViewModel,取决于你的应用复杂度和长期维护需求。

为什么有人说SwiftUI自带MVVM特性?

SwiftUI的@State、@Binding、@ObservableObject(iOS17+的@Observable)这些属性包装器,本身就承担了部分ViewModel的职责:

  • 视图内部的简单状态用@State管理,相当于把轻量状态逻辑内嵌在视图里
  • 跨视图共享状态用@ObservableObject,如果只是单纯持有状态,看起来和MV模式里的Model没差

这种情况下,对小型应用、单一视图或快速原型来说,直接用MV模式完全足够,显式写ViewModel确实显得冗余——没必要为了几个状态单独拆出一个类。

为什么MVVM依然适合SwiftUI?

当应用规模变大、业务逻辑复杂时,显式ViewModel的价值就凸显了:

  • 职责拆分清晰:把数据请求、业务判断、状态转换这些逻辑从视图里抽出来,视图只负责UI渲染和响应用户交互,代码可读性更高
  • 易于测试:ViewModel是纯Swift类,不依赖UI组件,能单独写单元测试验证业务逻辑,不用跑模拟器
  • 逻辑复用:多个视图可能用到相同的业务逻辑,ViewModel可以直接复用,避免重复造轮子
  • 状态管理可控:集中处理状态变化,不会让视图里散落大量逻辑,后期改需求、修bug更方便

实际场景怎么选?

  • 简单项目/快速验证:用MV模式,借助SwiftUI的状态包装器快速实现功能,不用过度设计
  • 中大型项目/长期维护:用MVVM架构,显式定义ViewModel,让代码结构更健壮,团队协作也更顺畅

举个直观对比:

  • MV模式(视图内嵌逻辑):
struct TodoView: View {
    @State private var todos: [Todo] = []
    
    var body: some View {
        List(todos) { todo in
            Text(todo.title)
        }
        .onAppear {
            Task {
                // 视图里直接处理数据请求
                todos = await TodoAPI.fetchTodos()
            }
        }
    }
}
  • MVVM模式(ViewModel处理逻辑):
@Observable
class TodoViewModel {
    var todos: [Todo] = []
    
    func fetchTodos() async {
        todos = await TodoAPI.fetchTodos()
    }
}

struct TodoView: View {
    @State private var viewModel = TodoViewModel()
    
    var body: some View {
        List(viewModel.todos) { todo in
            Text(todo.title)
        }
        .onAppear {
            Task {
                await viewModel.fetchTodos()
            }
        }
    }
}

后者把数据请求逻辑从视图中抽离,后续要加缓存、过滤逻辑,直接在ViewModel里改就行,不用动视图代码。

内容的提问来源于stack exchange,提问作者Jack_Frost

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 03:15:23