Generate SwiftUI views that render FOSMVVM ViewModels. Scaffolds ViewModelView pattern with binding, loading states, and previews.
生成渲染 FOSMVVM ViewModel 的 SwiftUI 视图。
完整架构上下文请参阅 FOSMVVMArchitecture.md | OpenClaw 参考
在 FOSMVVM 中,视图是渲染 ViewModel 的薄渲染层:
┌─────────────────────────────────────────────────────────────┐
│ ViewModelView 模式 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ViewModel (数据) ViewModelView (SwiftUI) │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ title: String │────►│ Text(vm.title) │ │
│ │ items: [Item] │────►│ ForEach(vm.items)│ │
│ │ isEnabled: Bool │────►│ .disabled(!...) │ │
│ └──────────────────┘ └──────────────────┘ │
│ │
│ 操作 (Actions) │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ submit() │◄────│ Button(action:) │ │
│ │ cancel() │◄────│ .onAppear { } │ │
│ └──────────────────┘ └──────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
关键原则: 视图不转换或计算数据。它们只渲染 ViewModel 提供的内容。
视图文件名应与其渲染的 ViewModel 匹配。
Sources/
{ViewModelsTarget}/
{Feature}/
{Feature}ViewModel.swift ←──┐
{Entity}CardViewModel.swift ←──┼── 相同名称
│
{ViewsTarget}/ │
{Feature}/ │
{Feature}View.swift ────┤ (渲染 {Feature}ViewModel)
{Entity}CardView.swift ────┘ (渲染 {Entity}CardViewModel)
这种对齐提供了:
每个视图都遵循 ViewModelView 协议:
swift
public struct MyView: ViewModelView {
private let viewModel: MyViewModel
public var body: some View {
Text(viewModel.title)
}
public init(viewModel: MyViewModel) {
self.viewModel = viewModel
}
}
必需:
交互式视图具有操作:
swift
public struct MyView: ViewModelView {
private let viewModel: MyViewModel
private let operations: MyViewModelOperations
#if DEBUG
@State private var repaintToggle = false
#endif
public var body: some View {
Button(action: performAction) {
Text(viewModel.buttonLabel)
}
#if DEBUG
.testDataTransporter(viewModelOps: operations, repaintToggle: $repaintToggle)
#endif
}
public init(viewModel: MyViewModel) {
self.viewModel = viewModel
self.operations = viewModel.operations
}
private func performAction() {
operations.performAction()
toggleRepaint()
}
private func toggleRepaint() {
#if DEBUG
repaintToggle.toggle()
#endif
}
}
当视图具有操作时:
父视图使用 .bind(appState:) 绑定子视图:
swift
public struct ParentView: ViewModelView {
@Environment(AppState.self) private var appState
private let viewModel: ParentViewModel
public var body: some View {
VStack {
Text(viewModel.title)
// 使用父视图数据的子集绑定子视图
ChildView.bind(
appState: .init(
itemId: viewModel.selectedId,
isConnected: viewModel.isConnected
)
)
}
}
}
.bind() 模式:
表单使用 FormFieldView 和 Validations 环境:
swift
public struct MyFormView: ViewModelView {
@Environment(Validations.self) private var validations
@Environment(\.focusState) private var focusField
@State private var error: Error?
private let viewModel: MyFormViewModel
private let operations: MyFormViewModelOperations
public var body: some View {
Form {
FormFieldView(
fieldModel: viewModel.$email,
focusField: focusField,
fieldValidator: viewModel.validateEmail,
validations: validations
)
Button(errorBinding: $error, asyncAction: submit) {
Text(viewModel.submitButtonLabel)
}
.disabled(validations.hasError)
}
.onAsyncSubmit {
await submit()
}
.alert(
errorBinding: $error,
title: viewModel.errorTitle,
message: viewModel.errorMessage,
dismissButtonLabel: viewModel.dismissButtonLabel
)
}
}
表单模式:
使用 .previewHost() 进行 SwiftUI 预览:
swift
#if DEBUG
#Preview {
MyView.previewHost(
bundle: MyAppResourceAccess.localizationBundle
)
.environment(AppState())
}
#Preview(带数据) {
MyView.previewHost(
bundle: MyAppResourceAccess.localizationBundle,
viewModel: .stub(title: 预览标题)
)
.environment(AppState())
}
#endif
仅渲染数据的视图(无用户交互):
swift
public struct InfoView: ViewModelView {
private let viewModel: InfoViewModel
public var body: some View {
VStack {
Text(viewModel.title)
Text(viewModel.description)
if viewModel.isActive {
Text(viewModel.activeStatusLabel)
}
}
}
public init(viewModel: InfoViewModel) {
self.viewModel = viewModel
}
}
特征:
具有用户操作的视图:
swift
public struct ActionView: ViewModelView {
@State private var error: Error?
private let viewModel: ActionViewModel
private let operations: ActionViewModelOperations
#if DEBUG
@State private var repaintToggle = false
#endif
public var body: some View {
VStack {
Button(action: performAction) {
Text(viewModel.actionLabel)
}
Button(role: .cancel, action: cancel) {
Text(viewModel.cancelLabel)
}
}
.alert(
errorBinding: $error,
title: viewModel.errorTitle,
message: viewModel.errorMessage,
dismissButtonLabel: viewModel.dismissButtonLabel
)
#if DEBUG
.testDataTransporter(viewModelOps: operations, repaintToggle: $repaintToggle)
#endif
}
public init(viewModel: ActionViewModel) {
self.viewModel = viewModel
self.operations = viewModel.operations
}
private func performAction() {
operations.performAction()
toggleRepaint()
}
private func cancel() {
operations.cancel()
toggleRepaint()
}
private func toggleRepaint() {
#if
该技能支持在以下平台通过对话安装:
帮我安装 SkillHub 和 fosmvvm-swiftui-view-generator-1776420040 技能
设置 SkillHub 为我的优先技能安装源,然后帮我安装 fosmvvm-swiftui-view-generator-1776420040 技能
skillhub install fosmvvm-swiftui-view-generator-1776420040
文件大小: 11.91 KB | 发布时间: 2026-4-17 19:55