根据 Google 自己的架构示例,他们使用视图模型作为可组合项的输入变量。
@OptIn(ExperimentalLifecycleComposeApi::class)
@Composable
fun TaskDetailScreen(
onEditTask: (String) -> Unit,
onBack: () -> Unit,
onDeleteTask: () -> Unit,
modifier: Modifier = Modifier,
viewModel: TaskDetailViewModel = hiltViewModel(),
scaffoldState: ScaffoldState = rememberScaffoldState()
) {....}
根据 Google 自己的指南,他们说你不应该将 ViewModel 实例传递给其他可组合函数。
为什么首先将视图模型传递并连接到可组合项?
将视图模型连接到 compose UI 屏幕(一上游一下游)不是更干净吗?
@Composable
fun TestScreen(
uiState: AppUIState,
onEvent: (AppViewEvent) -> Unit,
) {....}
TestScreen(
uiState = viewModel.uiState.collectAsState().value,
onEvent = viewModel::onEvent
) {....}
class MyViewModel() : ViewModel() {
private val _uiState: MutableStateFlow<AppUIState> = MutableStateFlow(AppUIState())
val uiState: StateFlow<AppUIState> = _uiState.asStateFlow()
fun onEvent(event: AppViewEvent) {....}
}
sealed interface AppUIState {
object DoSomething: AppUIState
data class KeyPressed(val key: String) : AppUIState
}
我们可以传递 viewModel 根级屏幕,但我们不应该传递它们的子级可组合函数。
您通常在屏幕级可组合项访问 ViewModel 实例,即靠近从导航图的活动、片段或目标调用的根可组合项。这是因为默认情况下 ViewModel 的范围仅限于那些屏幕级别对象。
在此处了解有关 ViewModel 的生命周期和范围的更多信息。
尽量避免将 ViewModel 实例传递给其他可组合项,因为这可能会使这些可组合项更难以测试,并且可能会破坏预览。相反,仅传递他们需要的数据和函数作为参数。
更多详情请参阅此处查看模型