HarmonyOS鸿蒙Next中MVVM模式(状态管理V2实现)
概述
在应用开发中,UI的更新需要随着数据状态的变化进行实时同步,而这种同步往往决定了应用程序的性能和用户体验。为了解决数据与UI同步的复杂性,ArkUI采用了Model-View-ViewModel(MVVM)架构模式。MVVM将应用分为Model、View和ViewModel三个核心部分,实现数据、视图与逻辑的分离。通过这种模式,UI可以随着状态的变化自动更新,无需手动处理,从而更加高效地管理数据和视图的绑定与更新。
Model:负责存储和管理应用的数据以及业务逻辑,不直接与用户界面交互。通常从后端接口获取数据,是应用程序的数据基础,确保数据的一致性和完整性。
View:负责用户界面展示数据并与用户交互,不包含任何业务逻辑。它通过绑定ViewModel层提供的数据来动态更新UI。
ViewModel:负责管理UI状态和交互逻辑。作为连接Model和View的桥梁,ViewModel监控Model数据的变化,通知View更新UI,同时处理用户交互事件并转换为数据操作。
示例
目录结构
--src/main/ets/pages/Index.ets:主页面
--src/main/ets/view/AddView.ets:新增任务组件
--src/main/ets/view/TitleView.ets:标题组件
--src/main/ets/view/ListView.ets:任务列表组件
--src/main/ets/model/TaskModel.ets:页面设计的数据结构
--src/main/ets/vm/TaskViewModel.ets:项目的交互逻辑组件
添加组件代码:
添加组件中的新增事件由父页面传入,新增的方法定义在TaskViewModel中,代码如下
import { TitleView } from '../view/TitleView';
import ListView from '../view/ListView';
import { TaskViewModel } from '../vm/TaskViewModel';
import { promptAction } from '@kit.ArkUI';
import { AddView } from '../view/AddView';
@Entry
@ComponentV2
struct Index {
@Local
taskVM: TaskViewModel = new TaskViewModel()
aboutToAppear(): void {
this.taskVM.queryTaskList()
promptAction.showToast({ message: this.taskVM.tasksList[1].taskName })
}
build() {
Column() {
TitleView({tasksUnfinished:this.taskVM.finishedCount})
AddView({
addTask:(taskName)=>{
this.taskVM.addTask(taskName)
}
})
ListView({
taskList: this.taskVM.tasksList,
delTask: (id) => {
this.taskVM.delTask(id)
},
changeFinished: (id, bool) => {
this.taskVM.updateTaskFinished(id, bool)
}
})
}
}
}
–src/main/ets/view/AddView.ets:新增任务组件
@ComponentV2
export struct AddView {
@Local
name: string = ''
@Event
addTask: (taskName: string) => void
build() {
Row() {
TextInput({ placeholder: '请输入任务名', text: $$this.name })
.layoutWeight(1)
Button('新增')
.onClick(() => {
this.addTask(this.name)
})
}
}
}
–src/main/ets/view/TitleView.ets:标题组件
@ComponentV2
export struct TitleView {
@Require
@Param tasksUnfinished:number
build() {
Column() {
Text('待办')
.fontSize(40)
.margin(10)
Text(`未完成任务:${this.tasksUnfinished}`)
.margin({ left: 10, bottom: 10 })
}
}
}
–src/main/ets/view/ListView.ets:任务列表组件
@ComponentV2
export default struct ListView {
@Require
@Param
taskList: TaskModel[]
//改变任务状态
@Event
changeFinished: (id:number,value: boolean) => void
@Event
delTask: (id: number) => void
build() {
Column() {
Row() {
Text('任务名')
.textAlign(TextAlign.Center)
.fontSize(18)
.layoutWeight(1)
Text('是否完成')
.textAlign(TextAlign.Center)
.fontSize(18)
.layoutWeight(1)
Text('操作')
.textAlign(TextAlign.Center)
.fontSize(18)
.layoutWeight(1)
}.width('100%')
List() {
ForEach(this.taskList, (item: TaskModel) => {
ListItem() {
Row() {
Text(item.taskName)
.textAlign(TextAlign.Center)
.fontSize(18)
.layoutWeight(1)
Text(item.isFinish ? '已完成' : '未完成')
.textAlign(TextAlign.Center)
.fontSize(18)
.fontColor(item.isFinish ? Color.Green : Color.Red)
.layoutWeight(1)
Button('完成')
.visibility(item.isFinish ? Visibility.Hidden : Visibility.Visible)
.onClick(() => {
this.changeFinished(item.tid,true)
})
Button('删除')
.onClick(() => {
this.delTask(item.tid)
})
}.width('100%')
}
})
}
}
}
}
–src/main/ets/model/TaskModel.ets:页面设计的数据结构
@ObservedV2
export default class TaskModel {
//任务ID
tid:number = 0
//任务名称
taskName: string = 'Todo';
//是否完成
@Trace
isFinish: boolean = false;
constructor(tid:number,taskName: string,isFinish: boolean) {
this.tid =tid
this.taskName = taskName
this.isFinish = isFinish
}
}
–src/main/ets/vm/TaskViewModel.ets:项目的交互逻辑组件
import TaskModel from "../model/TaskModel";
import { promptAction } from "@kit.ArkUI";
@ObservedV2
export class TaskViewModel {
//最大ID,用于新增数据
@Trace
maxId: number = 0
@Trace
finishedCount:number = 0
//需要显示的任务列表
@Trace tasksList: Array<TaskModel> = []
//接口获取数据,本次为演示无实际接口,暂时直接写死
queryTaskList() {
this.tasksList.push(new TaskModel(1, '吃饭', true))
this.tasksList.push(new TaskModel(2, '睡觉', true))
this.tasksList.push(new TaskModel(3, '打豆豆', false))
this.maxId = 3
this.finishedCount = 1
}
//计算未完成的个数
unFinished(){
this.finishedCount = 0
console.log('xx数组长度:'+this.tasksList.length);
for (let i = 0; i < this.tasksList.length; i++) {
if (!this.tasksList[i].isFinish) {
this.finishedCount++
}
}
}
//删除任务
delTask(id: number) {
for (let i = 0; i < this.tasksList.length; i++) {
if (this.tasksList[i].tid === id) {
this.tasksList.splice(i, 1)
this.unFinished()
return
}
}
}
//修改状态
updateTaskFinished(id: number, finished: boolean) {
for (let i = 0; i < this.tasksList.length; i++) {
if (this.tasksList[i].tid === id) {
this.tasksList[i].isFinish = finished
this.unFinished()
promptAction.showToast({ message: '修改了' })
return
}
}
}
//新增任务
addTask(name: string) {
this.maxId++
this.tasksList.push(new TaskModel(this.maxId,name,false))
this.unFinished()
}
}
更多关于HarmonyOS鸿蒙Next中MVVM模式(状态管理V2实现)的实战教程也可以访问 https://www.itying.com/category-93-b0.html
1 回复
更多关于HarmonyOS鸿蒙Next中MVVM模式(状态管理V2实现)的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中,MVVM模式通过状态管理V2实现,主要依赖@State
、@Prop
、@Link
等装饰器来管理UI状态。@State
用于组件内部状态管理,@Prop
用于父组件向子组件传递状态,@Link
用于双向绑定。通过ViewModel
层处理业务逻辑,View
层负责UI展示,实现数据与UI的分离,提升代码可维护性和可测试性。