object.defineproperties可批量注入crud行为:封装增删改查为描述符,操作私有_data并触发onchange通知;支持软删/硬删、id查找、数据合并;配合proxy可实现model[123]等自然语法。

直接用 Object.defineProperties 为数据模型注入完整 CRUD 行为,核心在于:**把增删改查逻辑封装成可复用的描述符对象,再批量挂载到目标对象上,同时确保操作能触发响应式更新(如通知视图刷新)**。它不替代 Vue/React 的响应系统,但适合轻量级、无框架或需精细控制的场景。
定义统一的 CRUD 描述符模板
先设计一套符合业务语义的属性描述符结构,每个方法都接收 payload 并返回结果,便于组合与测试:
- create:接收新数据对象,生成唯一 ID,推入内部数组,返回插入后的完整项
- read:支持按 ID 查单条,或不传参返回全部;可加过滤逻辑
-
update:按 ID 找到原对象,用
Object.assign合并更新字段,返回更新后对象 -
delete:按 ID 移除,返回被删项;支持软删(标记
isDeleted: true)或硬删
封装私有状态与响应触发机制
CRUD 方法需操作私有数据源(如 _data 数组),避免暴露原始结构。同时预留钩子(如 onChange)供外部监听变化:
前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。
const model = {
_data: [],
_nextId: 1,
onChange: null // 外部可赋值为 (action, item, list) => { /* 更新 UI 或发事件 */ }
};
所有 CRUD 方法末尾调用 this.onChange?.(action, item, this._data),实现解耦。
用 defineProperties 批量挂载行为
把四个方法包装成属性描述符,一次性注入。注意设 configurable: true 方便后续调试重写,enumerable: false 避免遍历时暴露:
Object.defineProperties(model, {
create: {
value(payload) {
const newItem = { id: this._nextId++, ...payload };
this._data.push(newItem);
this.onChange?.('create', newItem, this._data);
return newItem;
},
writable: true,
configurable: true,
enumerable: false
},
read: {
value(id) {
return id === undefined ? [...this._data] : this._data.find(item => item.id === id);
},
writable: true,
configurable: true,
enumerable: false
},
update: {
value({ id, ...updates }) {
const item = this._data.find(i => i.id === id);
if (item) Object.assign(item, updates);
this.onChange?.('update', item, this._data);
return item;
},
writable: true,
configurable: true,
enumerable: false
},
delete: {
value(id) {
const index = this._data.findIndex(i => i.id === id);
if (index > -1) {
const removed = this._data.splice(index, 1)[0];
this.onChange?.('delete', removed, this._data);
return removed;
}
},
writable: true,
configurable: true,
enumerable: false
}
});
配合 Proxy 实现更自然的访问语法(可选增强)
若希望支持 model[123] 直接读取、model[123] = {...} 更新,可用 Proxy 包裹 model,拦截 get/set/deleteProperty,内部委托给已注入的 CRUD 方法。这样既保留 defineProperties 的声明式定义优势,又获得类数组/对象的直觉用法。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










