一个高性能、内存安全且类型友好的 TypeScript 领域模型管理库。专为复杂的前端应用设计,支持 **自动内存管理 (WeakRef)**、**响应式框架集成 (Vue/MobX)** 以及 **精细化的数据合并策略**。
npm install @libeilong/model-manager一个高性能、内存安全且类型友好的 TypeScript 领域模型管理库。专为复杂的前端应用设计,支持 自动内存管理 (WeakRef)、响应式框架集成 (Vue/MobX) 以及 精细化的数据合并策略。
- 🚀 内存安全:基于 WeakRef 和 FinalizationRegistry 实现自动垃圾回收,防止内存泄漏。
- ⚡️ 响应式友好:支持 原地修改 (In-Place Mutation),完美适配 Vue (Reactive/Ref) 和 MobX 等响应式系统,保持引用稳定性。
- 🔄 智能合并:提供 replace、merge、append 多种策略处理嵌套关系和数组更新。
- 🔗 关系管理:轻松定义一对一、一对多关系,自动处理循环引用和延迟加载。
- 💎 类型增强:强大的 TypeScript 类型推导,自动生成 create 方法的输入类型定义。
- 📦 序列化控制:支持多种序列化策略(仅主键、完整对象、混合模式),灵活应对 API 提交需求。
``bash`
npm install model-manager或者
yarn add model-manager
你可以传入自定义的基类(如 Vue 的响应式基类),库会自动混入(Mixin)模型管理能力。
`typescript
import { createBaseModel, Model, PrimaryKey, Relation, PK_PROP } from 'model-manager'
// 模拟一个响应式基类 (适配 Vue/MobX 等)
class ReactiveBase {}
// 1. 创建基础模型,混入能力
@Model({ cache: false, serialization: 'hybrid' })
class BaseModel
// 声明 PK_PROP 用于类型推导窄化
declare [PK_PROP]: T
@PrimaryKey()
id: number = 0
createdAt: Date = new Date()
}
// 2. 定义 User 模型
@Model({ cache: true, mergeOnCacheHit: true, serialization: 'pk' })
class User extends BaseModel {
name: string = ''
email?: string
// 定义一对多关系,第二个参数 true 表示数组
@Relation(() => Order, true)
orders: Order[] = []
// 普通数组(非领域模型)
posts: Array<{ id: number; title: string }> = []
}
// 3. 定义 Order 模型
@Model({ cache: true, serialization: 'object' })
class Order extends BaseModel<'on'> {
// 自定义主键字段名
@PrimaryKey()
on: string = ''
title: string = ''
price?: number
// 定义一对一关系
@Relation(() => User)
creator!: User
}
`
`typescript
// 创建数据
const user = User.create({
id: 1,
name: 'Alice',
orders: [{ on: 'ORD-001', title: 'Book', price: 100 }],
})
// user.orders[0] 已经是 Order 类的实例
console.log(user.orders[0] instanceof Order) // true
// 再次创建相同 ID 的 User (缓存命中)
const user2 = User.create({
id: 1,
name: 'Alice Updated', // mergeOnCacheHit: true,属性会自动更新
})
console.log(user === user2) // true,引用完全相同
console.log(user.name) // "Alice Updated",实现原地更新
`
#### @Model(options: ModelOptions)
配置类的全局行为。
| 选项 | 类型 | 说明 | 默认值 |
| :---------------- | :----------------------------- | :------------------------------------------------------- | :--------- |
| cache | boolean | 是否启用实例缓存 | false |cacheStrategy
| | 'weak' \| 'strong' | 缓存策略。weak 使用弱引用(推荐),strong 为强引用。 | 'weak' |serialization
| | 'hybrid' \| 'pk' \| 'object' | 默认序列化策略。 | 'hybrid' |mergeOnCacheHit
| | boolean | 当 create 命中缓存时,是否自动合并新数据。 | false |primaryKey
| | string | 主键字段名(通常建议使用 @PrimaryKey 装饰器)。 | - |
#### @PrimaryKey()
标记类的属性为主键。库依赖主键进行缓存去重。
#### @Relation(targetGetter, isArray?, config?)
定义模型间的关联关系。
- targetGetter: () => Class。使用函数返回类,解决循环引用问题。isArray
- : boolean。是否为数组关系。config
- : 序列化配置等。
---
继承 createBaseModel 后,你的类将获得以下静态方法和实例方法。
#### 静态方法
- static create(data, options?)
创建或获取模型实例。如果缓存中存在且开启了缓存,则返回已有实例。
- data: 强类型的输入对象(支持递归嵌套)。options.merge
- : 强制覆盖类配置的合并行为。
- static createReference(pk)
仅通过主键创建一个“引用状态”的实例(标记为 isLoaded: false),常用于延迟加载场景。
- static find(pk)
从缓存中查找实例。
#### 实例方法
- merge(data, options?)
增量合并数据到当前实例。这是实现响应式更新的核心。
`typescript`
user.merge(
{ name: 'Bob' },
{
// 数组合并策略:
// 'replace' (默认): 以新数组为准,同步更新内容
// 'merge': 保留本地多余项,合并新项
// 'append': 追加新项
arrayStrategy: 'replace',
},
)
- serialize(options?)
将模型转换为普通 JSON 对象。
- 支持处理循环引用(自动降级为主键)。
- 根据 @Model 配置决定关系字段是输出 ID 还是完整对象。
- load(options?)
触发数据加载。需要用户在类上实现静态 _fetchData 方法。
`typescript
// 在类定义中实现
static async _fetchData(pk, context) {
return await api.getUser(pk);
}
// 调用
await user.load();
`
---
本库的设计初衷之一是配合现代前端框架。
- 原地修改 (In-Place Mutation):merge 方法会直接修改对象属性,而不是替换对象引用。createBaseModel(Base)
- 基类继承:通过 ,你可以传入 Vue 的类或其他基类,使得所有生成的 Model 实例天然具备响应式能力。
为了防止随着应用运行 Model 实例无限堆积,默认使用 WeakRef + FinalizationRegistry。
- 当 UI 组件卸载,不再持有 Model 引用时,GC 会自动回收 Model。
- 库会自动监听到回收事件,并从内部缓存 Map 中清理对应的 Key,防止内存泄漏。
在处理数组关系时(例如更新 user.orders):
- replace (默认):视为“同步”。后端返回的列表就是最新状态。本地多余的项会被移除,存在的项会原地更新属性,新的项会追加。
- merge`:视为“合并”。保留本地所有项,并把后端返回的数据更新进去。适用于“加载更多”或“增量推送”场景。