开天辟地 HarmonyOS(鸿蒙) - 状态管理: MVVM
开天辟地 HarmonyOS(鸿蒙) - 状态管理: MVVM
示例如下:
pages\state\mvvm\MVVMDemo.ets
/*
* mvvm - model, view ,viewmodel
* model - 负责数据的获取和存储,以及业务逻辑等,不与 view 关联
* view - 负责用户界面的展现,以及用户的输入等,不与 model 关联
* viewmodel - 是连接 model 和 view 的桥梁
* 负责将 model 的数据转为 view 的数据,并管理用户界面状态
* 负责处理用户的交互逻辑,并将相关数据交由 model 处理
*/
import { TaskListViewModel } from './viewmodel/MyViewModel';
import MyTopView from './view/MyTopView';
import MyListView from './view/MyListView';
import MyBottomView from './view/MyBottomView';
import { TitleBar } from '../../TitleBar';
import { LoadingDialog } from '@kit.ArkUI';
@Entry
@ComponentV2
struct MVVMDemo {
@Local taskList: TaskListViewModel = new TaskListViewModel()
loading: CustomDialogController = new CustomDialogController({
builder: LoadingDialog({ content: 'loading' }),
})
async aboutToAppear() {
this.loading.open()
await this.taskList.loadTasks();
this.loading.close()
}
get taskCount(): number {
return this.taskList.tasks.length
}
build() {
Column({space:10}) {
TitleBar()
MyTopView({ taskCount: this.taskCount })
MyListView({ taskList: this.taskList });
MyBottomView({ taskList: this.taskList });
}
.margin({left:10,right:10})
}
}
pages\state\mvvm\model\MyModel.ets
export class MyData {
tasks: ITaskModel[] = [];
constructor() {
}
async loadTasks() {
await new Promise<void>(r => setTimeout(r, 1000));
this.tasks.push({name:"task 1", done:false})
this.tasks.push({name:"task 2", done:false})
this.tasks.push({name:"task 3", done:false})
}
addTask(name: string, done: boolean) {
}
remove(name: string) {
}
updateAllTaskDone(done: boolean) {
}
updateTask(name: string, done: boolean) {
}
}
export interface ITaskModel {
name: string;
done: boolean;
};
pages\state\mvvm\view\MyTopView.ets
@ComponentV2
export default struct MyTopView {
@Param taskCount: number = 0;
build() {
Column() {
Text(`任务总数: ${this.taskCount}`)
}
}
}
pages\state\mvvm\view\MyBottomView.ets
import { TaskViewModel, TaskListViewModel } from '../viewmodel/MyViewModel';
@ComponentV2
export default struct MyBottomView {
@Param taskList: TaskListViewModel = new TaskListViewModel();
@Local newTaskName: string = '';
build() {
Column({space:10}) {
Row() {
Button('全部完成', { buttonStyle: ButtonStyleMode.NORMAL })
.onClick(() => {
this.taskList.updateAllTaskDone(true)
})
Blank(10)
Button('全部未完成', { buttonStyle: ButtonStyleMode.NORMAL })
.onClick(() => {
this.taskList.updateAllTaskDone(false)
})
}
Row() {
TextInput({ placeholder: '添加新任务', text: $$this.newTaskName }).layoutWeight(1)
Blank(10)
Button('+', { buttonStyle: ButtonStyleMode.NORMAL })
.onClick(() => {
let newTask = new TaskViewModel(this.newTaskName, false);
this.taskList.addTask(newTask);
this.newTaskName = '';
})
}
}
}
}
pages\state\mvvm\view\MyListView.ets
import { TaskViewModel, TaskListViewModel } from '../viewmodel/MyViewModel';
@ComponentV2
struct MyListItem {
@Param task: TaskViewModel = new TaskViewModel('', false);
@Event deleteTask: () => void = () => {};
@Event updateTask: () => void = () => {};
build() {
Row({space:10}) {
Image($r('app.media.app_icon')).width(24).height(24)
Text(this.task.name).fontSize(20)
Blank(10)
Button('删除').onClick(() => this.deleteTask())
}
.width('100%')
.height(50)
.padding({left:10, right:10})
.backgroundColor(this.task.done ? '#FFA500' : '#99f1f1f1')
.borderRadius(10)
.onClick(() => {
this.task.done = !this.task.done
this.updateTask()
})
}
}
@ComponentV2
export default struct MyListView {
@Param taskList: TaskListViewModel = new TaskListViewModel();
build() {
Repeat<TaskViewModel>(this.taskList.tasks)
.each((obj: RepeatItem<TaskViewModel>) => {
MyListItem({
task: obj.item,
deleteTask: () => this.taskList.removeTask(obj.item),
updateTask: () => this.taskList.updateTask(obj.item),
})
})
}
}
pages\state\mvvm\viewmodel\MyViewModel.ets
import { MyData, ITaskModel } from '../model/MyModel';
@ObservedV2
export class TaskViewModel {
@Trace name: string = '';
@Trace done: boolean = false;
public constructor(name: string, done: boolean) {
this.name = name;
this.done = done;
}
}
@ObservedV2
export class TaskListViewModel {
myData = new MyData();
@Trace tasks: TaskViewModel[] = [];
async loadTasks() {
await this.myData.loadTasks()
for(let task of this.myData.tasks){
let taskViewModel = new TaskViewModel(task.name, task.done);
this.tasks.push(taskViewModel)
}
}
updateAllTaskDone(done: boolean): void {
this.myData.updateAllTaskDone(done)
for(let task of this.tasks){
task.done = done;
}
}
addTask(task: TaskViewModel): void {
this.myData.addTask(task.name, task.done)
this.tasks.push(task);
}
removeTask(task: TaskViewModel): void {
this.myData.remove(task.name)
this.tasks.splice(this.tasks.indexOf(task), 1)
}
updateTask(task: TaskViewModel): void {
this.myData.updateTask(task.name, task.done)
}
}