MVVM V1状态管理 开发模式,看完即懂!
·
🎯 : MVVM V1状态管理 开发模式,看完即懂!
⭐⭐⭐⭐⭐⭐
📢 前言
- MVVM(Model-View-ViewModel)是一种前端开发中广泛应用的架构模式,通过数据绑定实现视图与业务逻辑的解耦
📌 核心概念
-
Model: 管理/存储业务数据与逻辑,以及数据结构,例如调用API接口curd(增删改查)的接口初始设定
-
View: 呈现用户界面,只要关注组件属性以及事件的改变与现实是否符合UX
-
ViewModel: 作为Model和View的中介层,将Model提供的原始数据进行加工给View进行现实,并且提供交互事件连接Model进行数据流转
🌳 结构图

🚀 模式优势
- 低耦合: 视图与业务逻辑分离,修改UI无需改动底层数据模型
- 事件驱动模式: 在中介层(ViewModel)规范了可能触发的事件,在(View)中执行对应的事件逻辑,职责清晰,维护性强
- 更好的分配团队任务: 基于MVVM模式分发模块,使得逻辑模块与UI设计模块可以并行开发,不同部分彼此独立
🔥🔥🔥 实战环节-基础列表点赞开发
🧱 MVVM模式组织结构
├── src
│ ├── ets
│ │ ├── components
│ │ │ ├──model
│ │ │ ├── ListItemModel.ets
│ │ │ └── ListModel.ets
│ │ │ ├──views
│ │ │ ├── ListComponent.ets
│ │ │ └── ListItemComponent.ets
│ │ │ ├──viewModel
│ │ │ ├── ListItemViewModel.ets
│ │ │ └── ListViewModel.ets
│ │ │ ├──ListIndexComp.ets
│ │ ├── pages
│ │ │ ├── Index.ets
│ └── resources
│ │ ├── rawfile
│ │ │ ├── listsDate.json
│
🧱 model
// model/ListItemModel.ets
/**
* 接口每项的字段
*/
export class ListItemModel {
label: string = ''
collect: boolean = false
}
// model/ListModel.ets
/**
* 提供原始数据和接口API设定
*/
import { common } from '@kit.AbilityKit'
import { util } from '@kit.ArkTS'
import { ListItemModel } from './ListItemModel'
export class ListModel {
lists: Array<ListItemModel> = []
async getMockDate(context: common.UIAbilityContext) {
const getJson = await context.resourceManager.getRawFileContent('listsDate.json')
const textDecoderOptions: util.TextDecoderOptions = { ignoreBOM: true }
const textDecoder = util.TextDecoder.create('utf-8', textDecoderOptions)
const result = textDecoder.decodeToString(getJson, { stream: false })
this.lists = JSON.parse(result)
}
}
🧱 view
// view/ListItemComponent.ets
/**
* 列表项(item)
*/
import ListItemViewModel from "../viewModel/ListItemViewModel"
@Component
export struct ListItemComponent {
@ObjectLink ListItemViewModel: ListItemViewModel
build() {
Row() {
Text(this.ListItemViewModel.label)
Blank()
Text()
.width(50)
.aspectRatio(1)
.borderRadius('50%')
.backgroundColor(this.ListItemViewModel.collect ? '#ff4cd1d6' : Color.Transparent)
.borderWidth(1)
.borderColor(Color.Black)
.onClick(() => {
this.ListItemViewModel.updateIsCollect(this.getUIContext())
})
}
.width('100%')
.height(80)
.padding({ left: 40, right: 20 })
.borderWidth(1)
.borderColor(Color.Black)
.borderRadius(12)
}
}
// view/ListComponent.ets
/**
* 列表循环
*/
import ListItemViewModel from "../viewModel/ListItemViewModel"
import { ListViewModelArray } from "../viewModel/ListViewModel"
import { ListItemComponent } from "./ListItemComponent"
@Component
export struct ListComponent {
@ObjectLink ListViewModelArray: ListViewModelArray
build() {
Column({ space: 4 }) {
ForEach(this.ListViewModelArray, (itemModel: ListItemViewModel) => {
ListItemComponent({ ListItemViewModel: itemModel })
})
}
}
}
🧱 viewModel
// viewModel/ListItemViewModel.ets
/**
* 列表(item)自身的事件定义
*/
import { ListItemModel } from "../model/ListItemModel"
@Observed
export default class ListItemViewModel {
@Track label: string = ''
@Track collect: boolean = false
setItemDate(item: ListItemModel) {
this.label = item.label
this.collect = item.collect
}
updateIsCollect(uiContext: UIContext): void {
this.collect = !this.collect
uiContext.getPromptAction().showToast({ message: this.collect ? '收藏成功' : '取消收藏' })
}
}
// viewModel/ListViewModel.ets
/**
* 中介层提供处理的好数据给视图展示
*/
import ListItemViewModel from "./ListItemViewModel"
import { common } from "@kit.AbilityKit"
import { ListModel } from "../model/ListModel"
// TODO: 这里需要继承Array<ListItemViewModel> 将自己包装成@Observed不然视图无法监听数据变化
@Observed
export class ListViewModelArray extends Array<ListItemViewModel> {
}
@Observed
export default class ListViewModel {
@Track lists: ListViewModelArray = new ListViewModelArray()
async getMockDate(context: common.UIAbilityContext) {
const result = new ListModel()
await result.getMockDate(context)
for (let item of result.lists) {
let listItemViewModel = new ListItemViewModel()
listItemViewModel.setItemDate(item)
this.lists.push(listItemViewModel)
}
}
}
🧱 ListIndexComp
// components/ListIndexComp.ets
/**
* 列表容器
*/
import { common } from "@kit.AbilityKit"
import { ListComponent } from "./views/ListComponent"
import ListViewModel from "./viewModel/ListViewModel"
@Component
export struct ListIndexComp {
private context = this.getUIContext().getHostContext() as common.UIAbilityContext
@State listViewModel: ListViewModel = new ListViewModel()
async aboutToAppear() {
await this.listViewModel.getMockDate(this.context)
}
build() {
ListComponent({ ListViewModelArray: this.listViewModel.lists })
}
}
🧱 listsDate
// src/main/resources/rawfile/listsDate.json
/**
* mock字段
* label 标题
* collect 收藏
*/
[
{"label": "后羿", "collect": false},
{"label": "孙尚香", "collect": false},
{"label": "黄忠", "collect": false},
{"label": "马可波罗", "collect": false},
{"label": "公孙离", "collect": false},
{"label": "狄仁杰", "collect": false},
{"label": "敖丙", "collect": false}
]
🎉 成果图

🌍️ 前往gitee仓库
📝 MVVM 架构通过数据绑定简化了视图和模型的交互,使代码结构更加清晰/线性和可维护,让我们可以在灵活性和复杂性之间取得平衡。
🌸🌼🌺
更多推荐

所有评论(0)