为什么Compose可组合项用viewModel()而Activity/Fragment用viewModels()
viewModel() 和 viewModels() 设计差异的核心原因
- 适用上下文体系不同
viewModels()是传统View体系下的KTX扩展函数,仅支持在Activity、Fragment中作为属性委托使用,默认绑定当前宿主的ViewModelStore,符合原生View开发的使用习惯。viewModel()是Jetpack Compose专属的可组合函数,仅能在Compose作用域内调用,除了支持绑定宿主Activity/Fragment的ViewModel实例外,还支持灵活绑定导航图目的地、某个Composable路由等更细粒度的作用域,适配声明式UI的开发逻辑。你在setContent{}中可以正常调用,是因为setContent本身就是Compose的入口作用域,默认持有宿主Activity的ViewModelStore,所以拿到的实例和Activity中用viewModels()获取的完全一致。 - 调用规则与灵活性不同
viewModels()采用Kotlin属性委托实现,必须在Activity/Fragment的成员变量位置初始化,不能在普通方法/局部作用域内随意调用,作用域只能是宿主本身。viewModel()是普通可组合函数,支持在任意Composable的局部作用域内调用,还可以通过传入自定义viewModelStoreOwner参数动态调整ViewModel的作用范围,适配Compose中嵌套路由、共享ViewModel等更灵活的场景。 - 适配的编程范式不同
viewModels()是为命令式的传统View开发设计,延续了Architecture Components推出以来的ViewModel使用规范,降低原有开发者的迁移成本。viewModel()是为Compose的声明式编程范式量身打造,符合Compose函数的生命周期管理规则,可在Composable重组时自动复用已有ViewModel实例,不需要依赖宿主的属性委托机制,适配声明式UI的开发逻辑。
内容的提问来源于stack exchange,提问作者Rawnak Yazdani
相关产品推荐
相关产品推荐

