Skip to content

ViewModel 规范

ViewModel 是 Feature 层与 Core 层的桥梁:负责请求仓库、管理弹窗/加载状态,并以 StateFlow 的形式提供给 Route 层。以下约定整理自项目内部的编码规范与现有业务示例。

基类选择

场景基类说明
无网络/纯导航BaseViewModel仅持有 AppNavigatorUserState,封装导航方法。
非分页网络请求BaseNetWorkViewModel<T>自带 BaseNetWorkUiState<T>executeRequest()retryRequest()
分页/列表BaseNetWorkListViewModel<T>扩展下拉刷新、上拉加载状态。

字段与注释

  • 类注释和方法注释必须包含功能描述与参数说明,方便团队协作。
  • StateFlow 命名使用完整语义,例如 couponModalVisiblespecModalVisible
  • 私有可变流 _xxx + 公共只读 xxx 的约定保持统一:
kotlin
private val _specModalVisible = MutableStateFlow(false)
val specModalVisible: StateFlow<Boolean> = _specModalVisible.asStateFlow()

路由参数读取

使用 SavedStateHandle.toRoute<Route>() 获取类型安全参数,并缓存下来:

kotlin
private val route = savedStateHandle.toRoute<UserRoutes.AddressDetail>()
private val addressId = route.addressId

状态收集

Route 层必须通过 collectAsState() 订阅状态:

kotlin
val uiState by viewModel.uiState.collectAsState()
val couponModalVisible by viewModel.couponModalVisible.collectAsState()

避免在 Screen/Content 层直接访问 ViewModel 字段,以免破坏可组合式更新。

UI 交互状态

所有 UI 交互(弹窗、动画、刷新)都应该通过 StateFlow 暴露:

kotlin
fun showCouponModal() { _couponModalVisible.value = true }
fun hideCouponModal() { _couponModalVisible.value = false }

Route 层收到状态后传递给 Screen/Content,避免在 Content 里使用 remember 保存业务状态。

导航与结果

  • 使用 navigate(route)navigateBack()navigateBackTo()popBackStackWithResult() 等封装方法。
  • 父页面需要刷新时,子页面调用 popBackStackWithResult(RefreshResultKey, true),父页面在 Route 层通过 observeRefreshState() 自动响应。

校验清单

  • [ ] 类/方法注释完整,说明用途与参数。
  • [ ] Mutable 状态全部封装为私有 _xxx,仅暴露只读 StateFlow
  • [ ] Route 层仅通过 collectAsState() 访问状态,Screen/Content 不直接引用 ViewModel。
  • [ ] 所有交互(弹窗、导航、刷新)都封装成清晰的函数,供 UI 层调用。
  • [ ] 网络请求通过 requestApiFlow() + executeRequest() 驱动,Loading/Error 已交给基类处理。

遵循这些规则即可让 Feature 层的 ViewModel 与 Core 能力无缝协作,也方便团队在其他业务模块中快速复用。