245 lines
9.3 KiB
Markdown
245 lines
9.3 KiB
Markdown
# MVVM框架
|
||
|
||
<cite>
|
||
**本文档引用的文件**
|
||
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md)
|
||
- [VMBase.md](file://doc/mvvm/VMBase.md)
|
||
- [VMCustom.md](file://doc/mvvm/VMCustom.md)
|
||
- [VMLabel.md](file://doc/mvvm/VMLabel.md)
|
||
- [VMState.md](file://doc/mvvm/VMState.md)
|
||
- [VMProgress.md](file://doc/mvvm/VMProgress.md)
|
||
- [VMEvent.md](file://doc/mvvm/VMEvent.md)
|
||
- [VMParent.md](file://doc/mvvm/VMParent.md)
|
||
- [ViewModelScript.md](file://doc/mvvm/ViewModelScript.md)
|
||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts)
|
||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts)
|
||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts)
|
||
</cite>
|
||
|
||
## 目录
|
||
1. [简介](#简介)
|
||
2. [核心组件](#核心组件)
|
||
3. [数据模型注册与管理](#数据模型注册与管理)
|
||
4. [UI组件与数据绑定机制](#ui组件与数据绑定机制)
|
||
5. [UI自动更新机制](#ui自动更新机制)
|
||
6. [编辑器配置与使用示例](#编辑器配置与使用示例)
|
||
7. [高级功能与最佳实践](#高级功能与最佳实践)
|
||
|
||
## 简介
|
||
|
||
Oops Plugin Framework的MVVM实现机制旨在通过数据驱动的方式简化UI逻辑开发,实现无代码或低代码的UI开发模式。该框架借鉴了Vue的设计理念,通过观察者模式和事件系统,实现了数据与UI的双向绑定。开发者无需频繁使用`cc.find`、`getChildByName`、`getComponent`等繁琐的DOM操作,而是通过简单的配置即可实现复杂的UI逻辑。
|
||
|
||
该框架的核心优势在于其组件化的实现方式,提供了多个低耦合的VM组件,如VMLabel、VMState、VMProgress等,这些组件可以直接在Cocos Creator编辑器中挂载和配置,极大地提高了开发效率和可维护性。
|
||
|
||
**Section sources**
|
||
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md#L1-L51)
|
||
|
||
## 核心组件
|
||
|
||
### ViewModel
|
||
ViewModel是MVVM框架的核心模块,负责动态管理数据模型,并通过`cc.director.emit`通知游戏内的节点组件状态变化。它是数据模型的包装器,提供了数据绑定、监听和通知的功能。
|
||
|
||
### VMBase
|
||
VMBase是所有VM组件的基类,实现了基础的数据绑定功能。其他VM组件如VMLabel、VMState等都继承自VMBase。它提供了路径监听、值变化回调等核心功能。
|
||
|
||
### VM组件类型
|
||
- **VMCustom**:通用组件,可自定义绑定任意组件的属性
|
||
- **VMLabel**:专门用于文本显示,支持模板语法和格式化
|
||
- **VMState**:根据数据值控制节点状态(激活、显示、颜色等)
|
||
- **VMProgress**:用于进度条显示,支持双向绑定
|
||
- **VMEvent**:在值变化时触发事件,调用其他组件的方法
|
||
- **VMParent**:用于定义局部范围的ViewModel数据
|
||
|
||
**Section sources**
|
||
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md#L14-L29)
|
||
- [VMBase.md](file://doc/mvvm/VMBase.md#L1-L38)
|
||
|
||
## 数据模型注册与管理
|
||
|
||
### 数据模型注册
|
||
通过`VM.add(data, 'tag')`方法注册数据模型,其中`data`是要绑定的数据对象,`tag`是该数据模型的唯一标识标签。注册后,该数据模型将被VMManager管理,可以通过标签进行访问和操作。
|
||
|
||
```typescript
|
||
// 构建数据对象
|
||
let data = {
|
||
name: 'user',
|
||
gold: 12200,
|
||
info: {
|
||
id: 0
|
||
}
|
||
}
|
||
// 创建VM对象并添加到VMManager进行管理,标记为'user'标签
|
||
VM.add(data, 'user');
|
||
```
|
||
|
||
### 数据模型管理API
|
||
- `add(data, tag)`:创建并添加ViewModel对象
|
||
- `get(tag)`:获取指定标签的ViewModel实例
|
||
- `remove(tag)`:移除指定标签的ViewModel对象
|
||
- `setValue(path, value)`:设置值(支持全局路径)
|
||
- `addValue(path, value)`:累加值
|
||
- `getValue(path, defaultValue)`:获取值(支持默认值)
|
||
|
||
**Section sources**
|
||
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md#L30-L51)
|
||
- [ViewModelScript.md](file://doc/mvvm/ViewModelScript.md#L20-L67)
|
||
|
||
## UI组件与数据绑定机制
|
||
|
||
### VMCustom组件
|
||
VMCustom是通用的绑定组件,可以绑定任意组件的任意属性。在编辑器中挂载VMCustom组件后,需要设置以下属性:
|
||
- **Controller**:启用后支持双向绑定
|
||
- **Watch Path**:要监听的数据路径
|
||
- **Component Name**:要绑定的组件名称
|
||
- **Component Property**:要绑定的组件属性
|
||
- **refreshRate**:刷新频率(仅在Controller启用时生效)
|
||
|
||
### VMLabel组件
|
||
VMLabel专门用于文本显示,支持模板语法和多种格式化方式。其主要特性包括:
|
||
- 支持单路径和多路径监听
|
||
- 使用`{{0}}`、`{{1}}`等模板语法
|
||
- 支持多种格式化:`int`(整数)、`fix(n)`(小数位数)、`kmbt`(千位分隔)、`per`(百分比)等
|
||
|
||
### VMState组件
|
||
VMState根据数据值控制节点状态,可以实现条件显示、颜色变化等功能。主要配置包括:
|
||
- **Watch Path**:监听的数据路径
|
||
- **Condition**:判断条件(如等于、大于等)
|
||
- **Value Action**:满足条件时执行的操作(如节点激活、可见性、不透明度、颜色等)
|
||
|
||
### VMProgress组件
|
||
VMProgress用于进度条显示,需要设置两个监听路径(最小值和最大值)。其配置与VMCustom类似,但专门针对进度条组件。
|
||
|
||
**Section sources**
|
||
- [VMCustom.md](file://doc/mvvm/VMCustom.md#L1-L17)
|
||
- [VMLabel.md](file://doc/mvvm/VMLabel.md#L1-L33)
|
||
- [VMState.md](file://doc/mvvm/VMState.md#L1-L41)
|
||
- [VMProgress.md](file://doc/mvvm/VMProgress.md#L1-L14)
|
||
|
||
## UI自动更新机制
|
||
|
||
### 事件驱动更新
|
||
当数据模型的值发生变化时,ViewModel会通过`cc.director.emit`触发事件,通知所有监听该路径的组件进行更新。这种事件驱动的机制确保了数据变化能够实时反映到UI上。
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A[修改数据模型] --> B{数据变化}
|
||
B --> C[ViewModel检测到变化]
|
||
C --> D[cc.director.emit触发事件]
|
||
D --> E[VM组件接收到通知]
|
||
E --> F[更新UI显示]
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [ViewModelScript.md](file://doc/mvvm/ViewModelScript.md#L69-L107)
|
||
|
||
### 双向绑定
|
||
通过启用VMCustom组件的Controller功能,可以实现UI到数据的反向绑定。例如,当用户拖动进度条时,不仅可以更新UI显示,还可以自动更新对应的数据模型值。
|
||
|
||
### 局部数据管理
|
||
对于局部组件,可以继承VMParent组件来管理局部数据。这种方式适用于弹窗等需要独立数据管理的场景。VMParent会在`onLoad`时自动将`*.name`形式的路径中的`*`替换为实际的ViewModel标签。
|
||
|
||
**Section sources**
|
||
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md#L30-L51)
|
||
- [VMParent.md](file://doc/mvvm/VMParent.md#L1-L23)
|
||
|
||
## 编辑器配置与使用示例
|
||
|
||
### HInfoComp组件分析
|
||
HInfoComp是英雄信息显示组件,展示了如何通过VM组件实现数据绑定:
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class HInfoComp {
|
||
+h_uuid : number
|
||
+heroNodes : Node[]
|
||
+update_data(uuid : number)
|
||
+load_all_hero(uuid : number)
|
||
+next_hero()
|
||
+prev_hero()
|
||
}
|
||
HInfoComp --> VMLabel : "使用"
|
||
HInfoComp --> VMProgress : "使用"
|
||
HInfoComp --> VMState : "使用"
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L1-L343)
|
||
|
||
### SIconComp组件分析
|
||
SIconComp是技能图标组件,展示了简单的数据绑定:
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class SIconCompComp {
|
||
+update_data(s_uuid : number)
|
||
}
|
||
SIconCompComp --> VMCustom : "使用"
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts#L1-L27)
|
||
|
||
### 编辑器配置步骤
|
||
1. 在节点上添加VM组件(如VMLabel、VMState等)
|
||
2. 设置Watch Path为对应的数据路径(如`user.gold`)
|
||
3. 配置组件特定属性(如VMLabel的模板格式)
|
||
4. 运行游戏,数据变化将自动反映到UI上
|
||
|
||
### 数值格式化示例
|
||
```typescript
|
||
// 在VMLabel中使用模板语法
|
||
// {{0:int}} 显示整数
|
||
// {{0:fix(2)}} 显示两位小数
|
||
// {{0:kmbt}} 使用K/M/B/T单位缩写
|
||
// {{0:per}} 显示百分比
|
||
// {{0:sep}} 使用千位分隔符
|
||
```
|
||
|
||
### 节点状态切换示例
|
||
```typescript
|
||
// 使用VMState控制节点状态
|
||
// Condition: value >= 30
|
||
// Value Action: NODE_VISIBLE
|
||
// Watch Nodes: 指定要控制的节点
|
||
```
|
||
|
||
### 进度条更新示例
|
||
```typescript
|
||
// 使用VMProgress更新进度条
|
||
// Watch Path Arr: [currentValue, maxValue]
|
||
// Component Name: ProgressBar
|
||
// Component Property: progress
|
||
```
|
||
|
||
**Section sources**
|
||
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L1-L343)
|
||
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts#L1-L27)
|
||
|
||
## 高级功能与最佳实践
|
||
|
||
### VMEvent组件
|
||
VMEvent组件可以在值变化时触发事件,调用其他组件的方法。适用于需要自定义处理逻辑的场景,如数值变化时播放动画、播放音效等。
|
||
|
||
### VMModify组件
|
||
VMModify组件提供了便捷的数据修改方法,可以通过事件调用实现数据的增减操作:
|
||
- `vAddInt`:增加整数
|
||
- `vSubInt`:减少整数
|
||
- `vMulInt`:乘以整数
|
||
- `vDivInt`:除以整数
|
||
- `vString`:设置字符串
|
||
- `vNumber`:设置数值
|
||
|
||
### 性能优化建议
|
||
1. 合理使用局部数据管理(VMParent),避免全局数据的过度监听
|
||
2. 控制刷新频率(refreshRate),避免不必要的频繁更新
|
||
3. 及时移除不再使用的ViewModel,防止内存泄漏
|
||
4. 避免过度嵌套使用VMParent,以免影响性能
|
||
|
||
### 调试技巧
|
||
1. 使用`VM.get(tag)`获取ViewModel实例进行调试
|
||
2. 通过`vm.active = false`临时关闭通知功能进行问题排查
|
||
3. 利用编辑器的组件配置界面直观地查看和修改绑定关系
|
||
|
||
**Section sources**
|
||
- [VMEvent.md](file://doc/mvvm/VMEvent.md#L1-L21)
|
||
- [VMModify.md](file://doc/mvvm/VMModify.md#L13-L29) |