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

SwiftUI中ViewModel的@Published数组父视图未同步更新问题如何解决

问题根因

你当前的两个视图各自初始化了独立的ViewModel实例,二者没有任何关联,子视图修改的是自己创建的ViewModel的属性,父视图的ViewModel自然收不到更新:

  1. CreateOrderView中用@ObservedObject var vwModel = ViewModel()创建了第一个实例A
  2. 子视图ListView中用@StateObject var vwModel = ViewModel()创建了第二个实例B
    你在子视图操作的是实例B的options,父视图的实例A的options一直是空数组,所以打印为空。

解决方案

核心是让父子视图共享同一个ViewModel实例,修改代码如下:

1. 修改父视图CreateOrderView的ViewModel声明

父视图作为ViewModel的持有者,要用@StateObject修饰(负责管理ViewModel的生命周期,避免视图重绘时实例被销毁重建):

struct CreateOrderView: View {
    // 改成@StateObject,作为ViewModel的持有者
    @StateObject var vwModel = ViewModel()
    var body: some View {
        // 把当前持有的ViewModel传给子视图
        ListView(vwModel: vwModel)
        Button(action: {
            print(vwModel.options) // 此时就能拿到子视图更新后的数组
            vwModel.addCart()
        }, label: {
            Text("Add")
            .frame(maxWidth: .infinity, minHeight: 60)
            .background(Color.red)
        })
    }
}

2. 修改子视图ListView的ViewModel声明

子视图不要自己创建ViewModel,改成接收外部传入的实例即可:

struct ListView: View{
    // 改成@ObservedObject,只接收外部传入的实例,不自己初始化
    @ObservedObject var vwModel: ViewModel
    var body: some View {
        List(vwModel.options) {row in
            // 原有展示逻辑不变
            print(vwModel.options) // 正常打印元素
        }
    }
}

扩展说明

如果你的视图层级很深,逐层传ViewModel比较麻烦,也可以用environmentObject的方式注入:

  • 在父视图的外层调用处添加.environmentObject(vwModel)
  • 子视图中用@EnvironmentObject var vwModel: ViewModel声明即可,不需要手动传参。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 06:39:00