我尝试在 SwiftUI 中正确实现 MVVM 方式,所以我想出了这个(简化的)模型和 ViewModel:
struct Model {
var property1: String
var property2: String
}
class ViewModel: ObservableObject {
@Published var model = Model(property1: "this is", property2: "a test")
}
Run Code Online (Sandbox Code Playgroud)
在 a 中使用它View
效果很好,但我遇到了一些糟糕的性能问题,因为我ViewModel
用一些计算属性和一些函数扩展了它(而且它Model
本身更复杂)。但让我们继续看这个例子,因为它完美地展示了我认为 SwiftUI 本身的一个大问题。
想象一下,您有这些视图来显示数据:
struct ParentView: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
print("redrawing ParentView")
return ChildView(viewModel: self.viewModel)
}
}
struct ChildView: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
print("redrawing ChildView")
return VStack {
ViewForTextField(property: self.$viewModel.model.property1)
ViewForTextField(property: self.$viewModel.model.property2)
}
}
}
struct ViewForTextField: View {
@Binding var property: String
var body: some View {
print("redrawing textView of \(self.property)")
return TextField("...", text: self.$property)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
}
Run Code Online (Sandbox Code Playgroud)
现在,在其中一条TextField
线索中输入文本,以重绘窗口中的每条线索! View
打印输出为:
redrawing ParentView
redrawing ChildView
redrawing textView of this is
redrawing textView of a test
redrawing ParentView
redrawing ChildView
redrawing textView of this isa
redrawing textView of a test
redrawing ParentView
redrawing ChildView
redrawing textView of this isab
redrawing textView of a test
...
Run Code Online (Sandbox Code Playgroud)
正如我所看到的,SwiftUI 重绘了每个视图,因为每个视图都在监听ObservedObject
.
我如何告诉 SwiftUI,它只应该重绘这些视图,到底在哪里发生了任何变化?
实际上,MVVM 意味着每个视图都有自己的模型,该模型会根据模型更改进行更新,而不是所有视图都有一个模型。
所以不需要观察viewModel
inParentView
因为它不依赖于它
struct ParentView: View {
var viewModel: ViewModel // << just member to pass down in child
var body: some View {
print("redrawing ParentView")
return ChildView(viewModel: self.viewModel)
}
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是分解视图模型,以便每个视图都有自己的视图子模型,该子模型将管理自己视图的更新。
归档时间: |
|
查看次数: |
1717 次 |
最近记录: |