鸿蒙Next MVVM思想总结

news/2024/12/16 13:22:15/文章来源:https://www.cnblogs.com/freerain/p/18609880

一、MVVM模式概述

在鸿蒙Next的ArkUI框架中,MVVM(Model-View-ViewModel)模式是一种重要的架构模式,用于管理应用程序中的数据和UI之间的交互。MVVM模式通过将数据和视图分离,使得应用程序的开发更加高效、可维护和可测试。

(一)MVVM模式的组成部分

  1. Model层:存储数据和相关逻辑的模型,表示组件或其他相关业务逻辑之间传输的数据,是对原始数据的进一步处理。
  2. View层:在ArkUI中通常是@Component装饰组件渲染的UI,负责展示数据给用户。
  3. ViewModel层:在ArkUI中,ViewModel是存储在自定义组件的状态变量、LocalStorage和AppStorage中的数据,起到数据与视图绑定的作用,负责处理数据的获取、更新和通知视图的变化。

(二)MVVM模式的工作原理

  1. 自定义组件通过执行其build()方法或者@Builder装饰的方法来渲染UI,即ViewModel可以渲染View。
  2. View可以通过相应event handler来改变ViewModel,即事件驱动ViewModel的改变,另外ViewModel提供了@Watch回调方法用于监听状态数据的改变。
  3. 在ViewModel被改变时,需要同步回Model层,以保证ViewModel和Model的一致性,即应用自身数据的一致性。

(三)ViewModel结构设计的目的

ViewModel结构设计应始终为了适配自定义组件的构建和更新,将Model和ViewModel分开的原因在于,目前很多关于UI构造和更新的问题,都是由于ViewModel的设计没有很好地支持自定义组件的渲染,或者试图让自定义组件强行适配Model层,而中间没有用ViewModel来进行分离。例如,直接将SQL数据库中的数据读入内存这种数据模型不能很好地直接适配自定义组件的渲染,所以在应用程序开发中需要适配ViewModel层。

二、ViewModel的数据源

(一)数据源类型及共享范围

  1. @State:组件级别的共享,通过命名参数机制传递,例如:CompA: ({ aProp: this.aProp }),表示传递层级(共享范围)是父子之间的传递。可以初始化多种状态变量,@Prop、@Link和@ObjectLink可以和其建立单向或双向同步。
  2. @Provide:组件级别的共享,可以通过key和@Consume绑定,因此不用参数传递,实现多层级的数据共享,共享范围大于@State。适合在单个页面UI组件树中共享状态数据。
  3. LocalStorage:页面级别的共享,可以通过@Entry在当前组件树上共享LocalStorage实例,可在ArkUI应用程序的几个页面上共享。
  4. AppStorage:应用全局的UI状态存储,和应用进程绑定,在整个应用内的状态数据的共享。是LocalStorage的单例对象,在页面中使用@StorageLink和@StorageProp为多个页面之间共享数据,还可使用PersistentStorage将其特定属性持久化到本地磁盘文件中,再次启动时恢复数据。

(二)不同数据源的使用示例

  1. @State装饰的变量与子组件共享状态数据
    • 例如在Parent组件中使用@State装饰testNum变量,并将其传递给LinkChildSibling子组件。在LinkChild组件中,@Link装饰的testNum与父组件的@State testNum建立双向同步,LinkChild中的更改会同步到父组件Parent,再从Parent同步到Sibling,同时也会同步给LinkChild的子组件LinkLinkChildPropLinkChild。而PropLinkChild中的@Prop和其父组件建立单向同步关系。
  2. @Provide装饰的变量与后代组件共享状态数据
    • 如在Parent组件中使用@Provide装饰testNum变量,在LinkChildSiblingLinkLinkChild等后代组件中使用@Consume创建双向同步,通过绑定相同的key连接,而不是通过组件构造函数参数传递,将更改从父组件传递到孙子组件更加方便。
  3. 给LocalStorage实例中对应的属性建立双向或单向同步
    • 创建LocalStorage实例并通过@Entry(storage)注入根节点,在Parent组件中初始化@LocalStorageLink("testNum")变量,会在LocalStorage实例中创建testNum属性并设置初始值。其子组件使用@LocalStorageLink@LocalStorageProp绑定同一个属性名key来传递数据,@LocalStorageLinkLocalStorage中对应属性的同步行为与@State@Link一致,为双向数据同步。
  4. 给AppStorage中对应的属性建立双向或单向同步
    • LocalStorage类似,在组件中使用@StorageLink@StorageProp为多个页面之间共享数据,如在ParentLinkChildSibling等组件中使用@StorageLink("testNum")@StorageProp("testNum")来共享和操作AppStorage中的testNum属性。

三、ViewModel的嵌套场景

(一)处理复杂类型数据

大多数情况下,ViewModel数据项是复杂类型,如对象数组、嵌套对象或其组合。对于嵌套场景,使用@Observed搭配@Prop或者@ObjectLink来观察变化。推荐设计单独的自定义组件来渲染每一个数组或对象,对于类和数组,@State、@Prop、@Link、@ObjectLink装饰的变量只能观察到第一层的变化,若要观察嵌套类内部对象的变化,可使用@ObjectLink或@Prop,优先考虑@ObjectLink,其通过嵌套对象内部属性的引用初始化自身,性能更好,@Prop会对嵌套内部对象进行深度拷贝来初始化,实现单向同步,但性能较慢。

(二)@Prop和@ObjectLink嵌套数据结构及区别

  1. 嵌套数据结构示例
    • 父组件ViewB渲染@State arrAArray<ClassA>),@State可观察新数组分配、数组项插入、删除和替换。子组件ViewA渲染每个ClassA对象,使用@ObjectLink a: ClassA可观察嵌套在Array内的ClassA对象的变化(前提是ClassA@Observed装饰)。不使用@Observed时,如ViewBthis.arrA[Math.floor(this.arrA.length/2)].c = 10的操作不会被观察到,相应ViewA组件也不会更新。
  2. @Prop和@ObjectLink的区别
    • 当在ViewA中将@ObjectLink替换为@Prop时,@Prop会对嵌套对象进行深度拷贝初始化,性能慢,且在一个ViewA中的属性赋值this.a.c += 1不会引发使用同一个ClassA初始化的其他ViewA的渲染更新,因为它们是不同的拷贝。而@ObjectLink通过引用共享对象,一个ViewA中属性改变会触发所有引用该对象的ViewA更新(前提是ClassA@Observed装饰)。

四、MVVM模式在鸿蒙Next中的优势

(一)简化UI设计和实现

通过ViewModel层的隔离,将UI与数据模型分离,使得UI的设计和实现更加简单,开发者可以专注于UI的展示逻辑,而不必关心数据的获取和存储细节。

(二)提高UI性能

MVVM模式能够更高效地更新UI,当数据发生变化时,只有相关的UI部分会被更新,而不是整个UI重新渲染,从而提高了应用程序的响应速度和性能。

(三)增强代码的可维护性和可测试性

数据和视图的分离使得代码结构更加清晰,易于维护和测试。可以单独对ViewModel层进行单元测试,验证数据的正确性和处理逻辑,同时也方便对UI层进行单独的测试和优化。

总之,鸿蒙Next的MVVM思想为应用程序开发提供了一种有效的架构模式,有助于提高开发效率、提升应用性能和改善代码质量。开发者在实际应用中应合理利用MVVM模式的特性,根据具体需求选择合适的数据源和处理嵌套数据结构的方式,以构建出高质量的应用程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/853753.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Win电脑端有什么好用的备忘录便签推荐?

一、sticky notes 中文名叫便笺,就是Windows电脑系统自带的便笺,打开即可直接使用,无需安装。 它是一个一个彩色便利贴形式展现的,可以记录文字、添加图片,适合记录一些简单的信息。 不支持一直悬挂在电脑桌面上显示,也不支持设置提醒时间,想要同步到手机端使用,也有点…

设备的分配与回收

设备的分配与回收 ‍ ​​ ‍一、设备分配时的考虑因素 ​​ (一)设备的固有属性独占设备:一个时段只能分配给一个进程(如打印机) 共享设备:可同时分配给多个进程使用(如磁盘),各进程往往是宏观上同时共享使用设备,而微观上交替使用。 虚拟设备:采用 SPOOLing 技术将…

GitHub项目迁移到GitLab

GitHub项目迁移到GitLab 1.克隆GitHub项目到本地 [root@gitclient ~]# mkdir gitrepos [root@gitclient ~]# cd gitrepos [root@gitclient gitrepos]# git init . hint: Using master as the name for the initial branch. This default branch name hint: is subject to chang…

极狐GitLab 正式发布安全补丁版本 17.6.2、17.5.4、 17.4.6

本分分享极狐GitLab 补丁版本 17.6.2, 17.5.4, 17.4.6 的详细内容。这几个版本包含重要的缺陷和安全修复代码,我们强烈建议所有私有化部署用户应该立即升级到上述的某一个版本。对于极狐GitLab SaaS,技术团队已经进行了升级,无需用户采取任何措施。 参考资料GitLab 专业升级…

IO应用程序接口设备驱动程序接口

IO应用程序接口&设备驱动程序接口 ‍ ​​ ‍一、输入/输出应用程序接口 背景:在设备独立软件层向上提供各种各样的输入/输出应用程序接口的原因是: 用户层的应用程序无法用一个统一的系统调用接囗来完成所有类型设备的 I/O ​​ ‍ 三种输入/输出应用程序接口:字符设备…

IO核心子系统

IO核心子系统 I/O 核心子系统要实现的功能就是中间三层要实现的功能。 前言:本节仅作介绍和导学,主要列举 I/O 子系统实现的相关功能,详细跳转至各对应节 ​​ ‍​​ ‍ 一、I/O 调度 用某种算法确定一个好的顺序来处理各个 I/O 请求。(类比进程调度) 如:磁盘调度(先来…

【日记】天气好好,然后打了两天游戏(562 字)

正文昨天和今天打了两天游戏,笑死。黑神话发布更新了,多打了几次虎先锋,今天晚上才过了二郎神。二郎神是真难啊。不过之后的法天相地战也是真帅啊。幸好之前没有看攻略被剧透一脸。除此之外好像就没做什么了。太懒了。中午吃饭,店家问我在读书还是工作了。后面我们聊起来。…

如何让 localStorage 数据实现实时响应

重大事项 📣 :重大事项提前通知!快来围观,不容错过! 极限科技 一直致力于为开发者和企业提供优质的开源工具,提升整个技术生态的活力。除了维护国内最流行的分词器 analysis-ik 和 analysis-pinyin,也在不断推动更多高质量开源产品的诞生。 在极限科技成立三周年之际,…

loadSend:免费开源局域网数据传输工具 全平台支持 传输工具

前言 不同系统的电脑、手机,文件传输有没有简单一点的方法? 手机是iPhone,电脑是Windows,如何更快捷传输文件呢? 我们最常用和用得最多的文件传输工具可能就是微信以及 QQ 了吧! 其实,如果只是在局域网内,用微信这一类聊天工具来传输文件并不算特别合适,除了可能存在的…

焦作本地在线教育系统价格

近年来,在线教育的普及使得传统教培模式受到了新的挑战。无论是大型教育集团,还是地方性的教培中心,纷纷转型线上,寻求更为灵活的盈利方式和发展机遇。在众多竞争者中,了解并运用合适的在线教育系统对维持市场地位至关重要。图源 凸知@www.tuzhi.ltd对于许多像焦作地区教育…

项目管理看板:实现任务透明化与实时跟踪

一、项目管理看板的定义与背景 1.1 什么是项目管理看板? 项目管理看板(Project Management Kanban)是一种可视化的任务管理工具,旨在帮助团队或项目管理者清晰地展示项目任务的状态,并对任务的进展进行实时跟踪。看板通常分为若干列,每一列代表任务的不同阶段(例如:待办…

实验六 C语言结构体、枚举应用编程

实验任务1 task1.c1 // P286例8.172 // 对教材示例代码作了微调,把输出学生信息单独编写成一个函数模块3 // 打印不及格学生信息、打印所有学生信息均调用该模块实现4 5 #include <stdio.h>6 #include <string.h> 7 #define N 3 // 运行程序输入测试时,可…