鸿蒙MVVM规范

0 阅读2分钟

其实ArkUI天生使用的就是MVVM架构,MVVM本质是把应用分为三个核心部分,Model(模型),View(视图)和ViewModel(视图模型),目的是让数据界面和逻辑分家,实现低耦合,各司其职。 流程:用户点击一下View告诉ViewModel我被点击了,ViewModel拿数据或改数据,数据发生了变化,View自动刷新,整个过程从头到尾,都不需要写任何setText()或者upadeUI()

分层目录结构

image.png

首先在工程中的est下创建三个目录分别是Model,View,ViewModel在这三个目录中新建ets文件,新建视图ets文件时要选择创建Page中的Empty Page
Model层代码主要是定义数据结构,在这里就简单演示一下,这是一个纯粹的数据定义,不掺和任何逻辑

export class TodoItem{
  id:number
  content:string
  completed:boolean
  constructor(id:number,content:string,completed:boolean) {
    this.id =id
    this.content = content
    this.completed = completed
  }
}

ViewModel是数据和逻辑的核心,所有逻辑都写在这里,在view界面层只需要调用即可,示例代码如下,值得注意的是在代码中使用了@Trace就必须加上@ObservedV2进行装饰,否则会报错

import{TodoItem}from '../model/TodoModel'

@ObservedV2
export class TodoViewModel{
  @Trace todoList:TodoItem[] = []
  constructor() {
    this.loadMockData()
  }

  private loadMockData():void{
    this.todoList = [
      new TodoItem(1,'学习资料',false),
      new TodoItem(2,'看完这期视频',false)
    ]
  }

  //添加数据
  addTodo(content:string):void{
    const newId = this.todoList.length+1
    const newTodo = new TodoItem(newId,content,false)
    this.todoList = [...this.todoList,newTodo]
  }

  toggleComplete(id:number):void{
    const index = this.todoList.findIndex(item=>item.id==id)
    if(index!==-1)
    {
      this.todoList[index].completed = !this.todoList[index].completed
      //触发更新
      this.todoList = [...this.todoList]
    }
  }


}

视图层view代码如下,本文只做简单的演示,主要是体现MVVM的架构思想,在真实的开发过程当中代码和逻辑会更加复杂

import{TodoItem}from'../model/TodoModel'
import{TodoViewModel}from'../viewmodel/TodoViewModel'

@ComponentV2
@Entry
struct TodoPage {
 private viewModel:TodoViewModel = new TodoViewModel()
  @Local inputText:string = ''

  build() {
    Column(){
      Text('我的待办')
        .fontSize(36)
        .fontWeight(FontWeight.Bold)
        .margin({top:20,bottom:20})

      //新增待办区域
      Row({space:10}){
        TextInput({placeholder:'请输入新任务',text:this.inputText})
          .onChange((value)=>{
            this.inputText = value
          })
          .layoutWeight(1)

        Button('添加')
          .onClick(()=>{
            if(this.inputText.trim())
            {
              this.viewModel.addTodo(this.inputText)
              this.inputText = ''
            }
          })
      }
      .width('90%')
      .margin({bottom:20})

      //待办列表
      List(){
        ForEach(this.viewModel.todoList,(item:TodoItem)=>{
          ListItem(){
            Row(){
              Checkbox({name:item.id.toString(),group:'toddGroup'})
                .select(item.completed)
                .onChange((value:boolean)=>{
                  this.viewModel.toggleComplete(item.id)
                })
              Text(item.content)
                .fontSize(18)
                .margin({left:10})
                .decoration({type:item.completed?TextDecorationType.LineThrough:TextDecorationType.None})
            }
            .padding(12)
          }
        })


      }.width('90%')
      .layoutWeight(1)
    }
    .height('100%')
    .width('100%')
  }
}

至此基本功能已经完善,使用MVVM架构不仅实现代码低耦合,改UI不伤逻辑,更方便团队合作,写单元测试,以及更加便捷的做后续代码的维护工作

在实际开发中我们可以把分层做的更加细致,这样更加利于我们代码的维护和拓展

image.png