complex-data
Advanced tools
+99
| # Complex Data | ||
| `complex-data` 是一个高度可组合、可扩展、由数据驱动的 UI 逻辑层框架。它旨在将复杂前端页面(尤其是表单、列表和数据表格)的状逻辑、数据流和交互行为,从具体的 UI 框架中解耦出来,通过一份结构化的数据(我们称之为“字典”)来进行定义和管理。 | ||
| ## 核心理念 | ||
| - **字典驱动 (Dictionary-driven)**: UI 的结构、行为和状态不再通过手写组件模板来定义,而是通过一份可序列化的 JavaScript 对象(字典)来描述。 | ||
| - **关注点分离 (Separation of Concerns)**: 框架本身是“无头 (Headless)”的,它只负责管理数据状态和业务逻辑,不关心最终的 UI 渲染。您可以将它与任何 UI 框架(如 Vue, React, Svelte 等)轻松集成。 | ||
| - **组合与继承 (Composition & Inheritance)**: 通过设计精良的类继承链和灵活的功能模块组合,可以轻松构建出从简单输入框到复杂可编辑列表的任意组件。 | ||
| - **内置响应式 (Built-in Reactivity)**: 框架内置了精简的响应式系统,能够自动处理组件之间的依赖关系、数据联动和状态更新。 | ||
| ## 主要功能 | ||
| - **丰富的组件定义**: 内置了对输入框、选择器、日期选择器、文件上传、嵌套表单、可编辑列表等多种常见业务组件的逻辑支持。 | ||
| - **强大的数据加载与缓存**: 组件可以配置异步数据加载逻辑,并内置了对 `localStorage` 的缓存支持,能够轻松实现远程搜索、数据持久化等功能。 | ||
| - **灵活的布局系统**: 通过 `GridParse` 栅格解析器,可以方便地定义组件的布局。 | ||
| - **声明式 API**: 提供了大量便捷的声明式 API,如通过简单配置即可实现复杂的日期禁用逻辑。 | ||
| - **高度可扩展**: 设计了强大的自定义组件工厂 (`createCustomEdit`),可以无缝集成任何非标准组件,并让其享受到框架的数据管理和响应式能力。 | ||
| - **健壮的类型安全**: 项目由 TypeScript 编写,提供了严谨的类型定义,尤其在泛型应用上保证了复杂数据结构下的类型安全。 | ||
| ## 安装 | ||
| ```bash | ||
| npm install complex-data | ||
| ``` | ||
| ## 快速开始 | ||
| 以下是一个定义简单登录表单的例子: | ||
| ```typescript | ||
| import { ComplexData } from 'complex-data'; | ||
| // 1. 定义表单字典 | ||
| const loginDictionary = [ | ||
| { | ||
| prop: 'username', | ||
| name: '用户名', | ||
| type: 'input', | ||
| required: true | ||
| }, | ||
| { | ||
| prop: 'password', | ||
| name: '密码', | ||
| type: 'input', | ||
| option: { | ||
| password: true | ||
| }, | ||
| required: true | ||
| }, | ||
| { | ||
| prop: 'loginBtn', | ||
| name: '登录', | ||
| type: 'button', | ||
| option: { | ||
| type: 'primary', | ||
| onClick: (payload) => { | ||
| // payload.form 是表单实例 | ||
| payload.form.validate().then(data => { | ||
| console.log('表单数据:', data); | ||
| // 在这里提交数据... | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| ]; | ||
| // 2. 创建 ComplexData 实例 | ||
| const loginForm = new ComplexData({ | ||
| dictionary: loginDictionary | ||
| }); | ||
| // 3. 在你的 UI 框架中渲染 | ||
| // - 遍历 loginForm.getPageList() 获取渲染列表 | ||
| // - 将每个组件的属性 (item.name, item.prop, item.$option 等) 传递给你的 UI 组件 | ||
| // - 通过 item.setValue(newValue) 更新数据 | ||
| // - 通过 item.getValue() 获取数据 | ||
| // - 监听 item.$on('change', ...) 来响应数据变化 | ||
| ``` | ||
| ## 架构概览 | ||
| - `src/data/`: 定义了项目的核心数据模型基类,如 `Data`, `SimpleData`, `ComplexData`。 | ||
| - `src/module/`: 封装了可复用的功能模块,如 `SearchData`, `PaginationData`, `StatusData` 等。 | ||
| - `src/core/`: 包含核心的业务逻辑,如 `ComplexInfo` (单条数据) 和 `ComplexList` (数据列表)。 | ||
| - `src/lib/`: 提供了一系列工具类和值对象,如 `FormValue`, `SelectValue`, `GridParse` 等。 | ||
| - `src/dictionary/`: 包含了所有内置组件的定义,是整个字典系统的核心实现。 | ||
| ## 依赖 | ||
| - [`complex-utils`](https://github.com/MarAngle/complex-utils): 提供核心的工具函数和基类。 | ||
| ## 贡献 | ||
| 欢迎提交问题 (issues) 和合并请求 (pull requests)。 | ||
| ## 许可证 | ||
| [MIT](https://opensource.org/licenses/MIT) |
| import { describe, it, expect } from 'vitest' | ||
| import Data from './Data' | ||
| describe('Data', () => { | ||
| it('should be instantiable without arguments', () => { | ||
| const dataInstance = new Data() | ||
| expect(dataInstance).toBeInstanceOf(Data) | ||
| }) | ||
| it('should have a unique ID', () => { | ||
| const instance1 = new Data() | ||
| const instance2 = new Data() | ||
| // _getId() is a public method to access the internal ID | ||
| expect(instance1._getId()).not.toBe(instance2._getId()) | ||
| }) | ||
| it('should set and get a parent', () => { | ||
| const parent = new Data() | ||
| const child = new Data() | ||
| child.$setParent(parent) | ||
| expect(child.$getParent()).toBe(parent) | ||
| }) | ||
| }) |
| import { defineConfig } from 'vitest/config' | ||
| export default defineConfig({ | ||
| test: { | ||
| environment: 'jsdom', | ||
| }, | ||
| }) |
+286
-279
@@ -24,457 +24,464 @@ | ||
| ### 4.9.7/8 | ||
| - fix:修正TrackData.resetStatus错误的将init设置为false导致在pushData时判断错误出现额外生成icon的BUG | ||
| - feat:优化轨迹数据的整体逻辑 | ||
| ### 4.10.1 | ||
| - refactor(build): 移除项目的所有构建配置,回归到纯源码模式。 | ||
| - feat(test): 完善 `Vitest` 单元测试流程,并实现了基础的单元测试架构。 | ||
| - docs(readme): 优化 `README.md` 文件。 | ||
| - chore(history): 全面优化和重构 `history.md` 的格式。 | ||
| - fix(cache): 修正 `StorageValue` 中基于读取次数的缓存过期机制未正确计数导致无法过期的 BUG。 | ||
| - refactor(grid): 移除 `GridParse` 中未使用的冗余代码。 | ||
| ### 4.9.8 | ||
| - fix(track): 修正 `TrackData.resetStatus` 错误的将 `init` 设置为 `false` 的 BUG。 | ||
| - feat(track): 优化轨迹数据的整体逻辑。 | ||
| ### 4.9.6 | ||
| - fix:修正TrackData.pushData在无数据和无地图覆盖物的初始状态修正,以及未正确计算maxIndex和dict的BUG | ||
| - fix(track): 修正 `TrackData.pushData` 在无数据和无地图覆盖物的初始状态修正,以及未正确计算 `maxIndex` 和 `dict` 的 BUG。 | ||
| ### 4.9.5 | ||
| - feat:TrackData的line/connect的变量名优化 | ||
| - fix:修正TrackData.stop | ||
| - refactor(track): `TrackData` 的 `line/connect` 的变量名优化。 | ||
| - fix(track): 修正 `TrackData.stop`。 | ||
| ### 4.9.4 | ||
| - fix:修正TrackData.pushData未重新计算maxIndex的BUG | ||
| - fix(track): 修正 `TrackData.pushData` 未重新计算 `maxIndex` 的 BUG。 | ||
| ### 4.9.3 | ||
| - feat:TrackData添加pushData方法 | ||
| - fix:修正TrackData.$setIndex在未传递currentIndex时,在结束时错误将this.$index.next.data设置为溢出index的BUG | ||
| - feat(track): `TrackData` 添加 `pushData` 方法。 | ||
| - fix(track): 修正 `TrackData.$setIndex` 在未传递 `currentIndex` 时,在结束时错误将 `this.$index.next.data` 设置为溢出 `index` 的 BUG。 | ||
| ### 4.9.2 | ||
| - feat:优化TrackData轨迹数据 | ||
| - feat(track): 优化 `TrackData` 轨迹数据。 | ||
| ### 4.9.1 | ||
| - feat:修改模块加载逻辑为ES2020 | ||
| - feat(module): 修改模块加载逻辑为 ES2020。 | ||
| ### 4.8.14/15 | ||
| - feat:config=>dataConfig,dataConfig添加style属性,输出dataConfig | ||
| ### 4.8.15 | ||
| - feat(config): `config` => `dataConfig`, `dataConfig` 添加 `style` 属性, 输出 `dataConfig`。 | ||
| ### 4.8.13 | ||
| - feat:扩展SelectValue数据,添加$color属性,此属性存在时取全局color值进行动态赋值 | ||
| - feat(select): 扩展 `SelectValue` 数据,添加 `$color` 属性,此属性存在时取全局 `color` 值进行动态赋值。 | ||
| ### 4.8.12 | ||
| - feat:BaseData的triggerMethodOption的throttle=>debounce,更贴近实际功能防抖 | ||
| - fix:SelectEdit将$searchData函数并入loadData函数中实现,避免加载时的错误调用 | ||
| - fix:SelectEdit在每次检索时都保存当前检索值,避免BUG | ||
| - feat(events): `BaseData` 的 `triggerMethodOption` 的 `throttle` => `debounce`,更贴近实际功能防抖。 | ||
| - fix(select): `SelectEdit` 将 `$searchData` 函数并入 `loadData` 函数中实现,避免加载时的错误调用。 | ||
| - fix(select): `SelectEdit` 在每次检索时都保存当前检索值,避免 BUG。 | ||
| ### 4.8.10/11 | ||
| - feat:DefaultSelectEdit添加filter函数,实现自定义加载list的逻辑 | ||
| ### 4.8.11 | ||
| - feat(select): `DefaultSelectEdit` 添加 `filter` 函数,实现自定义加载 `list` 的逻辑。 | ||
| ### 4.8.9 | ||
| - 修正SelectValue初始化时未正确赋值equal/hidden/miss的BUG | ||
| - fix(select): 修正 `SelectValue` 初始化时未正确赋值 `equal/hidden/miss` 的 BUG。 | ||
| ### 4.8.8 | ||
| - 修正FileEdit的multiple被错误的传递为false的BUG | ||
| - fix(file): 修正 `FileEdit` 的 `multiple` 被错误的传递为 `false` 的 BUG。 | ||
| ### 4.8.7 | ||
| - 优化ComplexInfo.$info的类型 | ||
| - refactor(types): 优化 `ComplexInfo.$info` 的类型。 | ||
| ### 4.8.6 | ||
| - 简化SelectValue/CascaderValue数据类型,删除DefaultSelectValueType/DefaultCascaderValueType | ||
| - refactor(types): 简化 `SelectValue/CascaderValue` 数据类型,删除 `DefaultSelectValueType/DefaultCascaderValueType`。 | ||
| ### 4.8.4/5 | ||
| - 优化DictionaryValue的_initEditMod函数逻辑 | ||
| - 添加DefaultSelectEdit数据,调整SelectEdit基于DefaultSelectEdit实现 | ||
| - 添加createCustomEdit函数创建自定义组件,添加CustomLoadEdit组件 | ||
| - 全局添加DefaultEdit的泛型M | ||
| - 优化createCustomEdit的返回值,修正类型报错 | ||
| - SearchData添加inited生命周期,对应字典构建完成生命周期 | ||
| - ComplexData添加$onSearchInited=>在检索加载完成后触发回调函数,loadDataBySearchInited=>在检索加载完成后触发数据加载函数 | ||
| - 基于AI优化代码 | ||
| ### 4.8.5 | ||
| - refactor(dictionary): 优化 `DictionaryValue` 的 `_initEditMod` 函数逻辑。 | ||
| - feat(select): 添加 `DefaultSelectEdit` 数据,调整 `SelectEdit` 基于 `DefaultSelectEdit` 实现。 | ||
| - feat(custom): 添加 `createCustomEdit` 函数创建自定义组件,添加 `CustomLoadEdit` 组件。 | ||
| - refactor(types): 全局添加 `DefaultEdit` 的泛型 `M`。 | ||
| - refactor(custom): 优化 `createCustomEdit` 的返回值,修正类型报错。 | ||
| - feat(events): `SearchData` 添加 `inited` 生命周期,对应字典构建完成生命周期。 | ||
| - feat(events): `ComplexData` 添加 `$onSearchInited` => 在检索加载完成后触发回调函数, `loadDataBySearchInited` => 在检索加载完成后触发数据加载函数。 | ||
| - refactor(code): 基于 AI 优化代码。 | ||
| ### 4.8.2/3 | ||
| - 添加TrackData轨迹数据结构 | ||
| ### 4.8.3 | ||
| - feat(track): 添加 `TrackData` 轨迹数据结构。 | ||
| ### 4.8.1 | ||
| - 稳定版 | ||
| - chore: 稳定版。 | ||
| ### 4.6.36 | ||
| - utils依赖升级 | ||
| - chore(deps): `utils` 依赖升级。 | ||
| ### 4.6.32 | ||
| - utils依赖升级 | ||
| - 非兼容性更新:DefaultData._getRealName => DefaultData._getProp | ||
| - chore(deps): `utils` 依赖升级。 | ||
| - refactor(data)!: **[非兼容性更新]** `DefaultData._getRealName` => `DefaultData._getProp`。 | ||
| ### 4.6.31 | ||
| - 非兼容性更新 | ||
| - - 类型 | ||
| - - - DefaultModOffsetSort=>删除 | ||
| - - - DefaultModBeforeSort=>DefaultModBeforeOrder | ||
| - - - DefaultModAfterSort=>DefaultModAfterOrder | ||
| - - - DefaultModSort=>DefaultModOrder | ||
| - - 结构 | ||
| - - - DefaultMod.sort=>DefaultMod.order | ||
| - refactor(sort)!: **[非兼容性更新]** | ||
| - **类型**: | ||
| - `DefaultModOffsetSort` => 删除 | ||
| - `DefaultModBeforeSort` => `DefaultModBeforeOrder` | ||
| - `DefaultModAfterSort` => `DefaultModAfterOrder` | ||
| - `DefaultModSort` => `DefaultModOrder` | ||
| - **结构**: | ||
| - `DefaultMod.sort` => `DefaultMod.order` | ||
| ### 4.6.30 | ||
| - SortData排序数据修正BUG,整体逻辑优化 | ||
| - ResetData添加sort配置项 | ||
| - ComplexData适配sort全局函数 | ||
| - fix(sort): `SortData` 排序数据修正 BUG, 整体逻辑优化。 | ||
| - feat(reset): `ResetData` 添加 `sort` 配置项。 | ||
| - feat(sort): `ComplexData` 适配 `sort` 全局函数。 | ||
| ### 4.6.28/29 | ||
| - 非兼容性更新:ForceValue初始化传参优化 | ||
| - 新增ResetDat数据,实现根据主数据状态自动reset的数据类型,设置为ChoiceData的父类 | ||
| - 添加SortData排序数据 | ||
| ### 4.6.29 | ||
| - refactor(choice)!: **[非兼容性更新]** `ForceValue` 初始化传参优化。 | ||
| - feat(reset): 新增 `ResetData` 数据,实现根据主数据状态自动 `reset` 的数据类型,设置为 `ChoiceData` 的父类。 | ||
| - feat(sort): 添加 `SortData` 排序数据。 | ||
| ### 4.6.27 | ||
| - utils依赖升级 | ||
| - 非兼容性更新:ForceValue添加trigger属性,优化choice触发数据 | ||
| - 优化ChoiceData | ||
| - chore(deps): `utils` 依赖升级。 | ||
| - refactor(choice)!: **[非兼容性更新]** `ForceValue` 添加 `trigger` 属性, 优化 `choice` 触发数据。 | ||
| - refactor(choice): 优化 `ChoiceData`。 | ||
| ### 4.6.26 | ||
| - utils依赖升级 | ||
| - DefaultEdit添加deepClone初始化参数,当为真时,对传入数据为复杂数据时编辑进行深拷贝:暂不进行自动判断逻辑,仅自动生成parse函数 | ||
| - chore(deps): `utils` 依赖升级。 | ||
| - feat(edit): `DefaultEdit` 添加 `deepClone` 初始化参数,当为真时,对传入数据为复杂数据时编辑进行深拷贝。 | ||
| ### 4.6.25 | ||
| - CustomEdit的model配置项优化,change字段可配置其他字段,设置双向绑定参数;handler可配置指定双向绑定函数 | ||
| - DefaultMod删除reactives相关配置项 | ||
| - feat(custom): `CustomEdit` 的 `model` 配置项优化,`change` 字段可配置其他字段,设置双向绑定参数;`handler` 可配置指定双向绑定函数。 | ||
| - refactor(mod): `DefaultMod` 删除 `reactives` 相关配置项。 | ||
| ### 4.6.23/24 | ||
| - utils依赖升级 | ||
| - DefaultEdit类添加静态函数$parseRuleList | ||
| - DefaultEdit.getRuleList => parseRuleList | ||
| - multiple && required时自动校验数据不为空数组 | ||
| ### 4.6.24 | ||
| - chore(deps): `utils` 依赖升级。 | ||
| - refactor(edit): `DefaultEdit.getRuleList` => `parseRuleList`。 | ||
| - feat(validation): `multiple && required` 时自动校验数据不为空数组。 | ||
| ### 4.6.21/22 | ||
| - FileEdit当option的image存在时,accept的默认值改为image/* | ||
| - 优化FormEdit/ListEdit | ||
| ### 4.6.22 | ||
| - feat(file): `FileEdit` 当 `option` 的 `image` 存在时,`accept` 的默认值改为 `image/*`。 | ||
| - refactor(edit): 优化 `FormEdit/ListEdit`。 | ||
| ### 4.6.20 | ||
| - 全局Promise返回逻辑优化 | ||
| - refactor(promise): 全局 Promise 返回逻辑优化。 | ||
| ### 4.6.19 | ||
| - 添加默认宽度 | ||
| - feat(layout): 添加默认宽度。 | ||
| ### 4.6.17/18 | ||
| - 非兼容性更新:ComplexData的常见方法去除$符,添加全局拦截,实现基础的dataChange生命周期 | ||
| ### 4.6.18 | ||
| - refactor(api)!: **[非兼容性更新]** `ComplexData` 的常见方法去除 `$` 符, 添加全局拦截, 实现基础的 `dataChange` 生命周期。 | ||
| ### 4.6.16 | ||
| - 非兼容性更新:DefaultSimpleEdit.disabled作为高频率的差异化值更改为InterfaceValue结构 | ||
| - refactor(edit)!: **[非兼容性更新]** `DefaultSimpleEdit.disabled` 作为高频率的差异化值更改为 `InterfaceValue` 结构。 | ||
| ### 4.6.15 | ||
| - 文件上传扩展isUrl配置项,为真则说明值为url | ||
| - feat(file): 文件上传扩展 `isUrl` 配置项, 为真则说明值为 url。 | ||
| ### 4.6.12/13 | ||
| - 因ts类型报错:不能将扩展类的实例成员函数覆盖到类的属性与实例成员属性上,优化ComplexData的常见函数到类实例成员属性上,实现可继承赋值可改写 | ||
| ### 4.6.13 | ||
| - refactor(data): 因 ts 类型报错, 优化 `ComplexData` 的常见函数到类实例成员属性上, 实现可继承赋值可改写。 | ||
| ### 4.6.11 | ||
| - defaultFileOption的image属性扩展 | ||
| - feat(file): `defaultFileOption` 的 `image` 属性扩展。 | ||
| ### 4.6.10 | ||
| - icon:plus=>build/upload=>import/download=>export | ||
| - refactor(icon): `icon:plus` => `build/upload` => `import/download` => `export`。 | ||
| ### 4.6.9 | ||
| - DefaultMod添加hidden/frozen属性,该属性与observer.hidden/frozen属性使用场景不同,用于本身一直是隐藏状态或者冻结状态的模块,避免隐藏状态需要开启监听 | ||
| - 修正DateRangeEditInitOption类型 | ||
| - feat(mod): `DefaultMod` 添加 `hidden/frozen` 属性,用于本身一直是隐藏/冻结状态的模块。 | ||
| - fix(types): 修正 `DateRangeEditInitOption` 类型。 | ||
| ### 4.6.8 | ||
| - SelectValueType类型不作为基类,避免赋值时需要额外进行类型断言的问题 | ||
| - defaultFileOption类型添加image属性,此属性标明此文件上传为图片类型,可通过组件模板实现图片查看机制 | ||
| - refactor(types): `SelectValueType` 类型不作为基类,避免赋值时需要额外进行类型断言的问题。 | ||
| - feat(file): `defaultFileOption` 类型添加 `image` 属性,标明此文件上传为图片类型。 | ||
| ### 4.6.2/3/4/5/6/7 | ||
| - utils依赖升级 | ||
| - 添加列表编辑ListEdit | ||
| - 优化MenuValue数据,添加hidden隐藏配置项,添加confirm确认配置项 | ||
| ### 4.6.7 | ||
| - chore(deps): `utils` 依赖升级。 | ||
| - feat(edit): 添加列表编辑 `ListEdit`。 | ||
| - feat(menu): 优化 `MenuValue` 数据,添加 `hidden` 隐藏配置项,添加 `confirm` 确认配置项。 | ||
| ### 4.6.1 | ||
| - utils依赖升级 | ||
| - 优化排序相关逻辑 | ||
| - chore(deps): `utils` 依赖升级。 | ||
| - refactor(sort): 优化排序相关逻辑。 | ||
| ### 4.4.6 | ||
| - DefaultMod添加排序参数 | ||
| - DictionaryData添加排序静态函数,getPageList/getObserveList时基于DefaultMod.$sort进行额外排序 | ||
| - feat(sort): `DefaultMod` 添加排序参数。 | ||
| - feat(dictionary): `DictionaryData` 添加排序静态函数,`getPageList/getObserveList` 时基于 `DefaultMod.$sort` 进行额外排序。 | ||
| ### 4.4.5 | ||
| - utils依赖升级 | ||
| - SearchData在reset时重置formData | ||
| - chore(deps): `utils` 依赖升级。 | ||
| - fix(search): `SearchData` 在 `reset` 时重置 `formData`。 | ||
| ### 4.4.4 | ||
| - SelectValue添加getIndex/getItemByIndex/getItemByOffset函数,实现快速获取相关联数据逻辑 | ||
| - 修正DictionaryValue调用$formatInitOption的类型标注错误 | ||
| - feat(select): `SelectValue` 添加 `getIndex/getItemByIndex/getItemByOffset` 函数。 | ||
| - fix(types): 修正 `DictionaryValue` 调用 `$formatInitOption` 的类型标注错误。 | ||
| ### 4.4.2/3 | ||
| - 优化依赖相关功能,依赖实现创建时加载和数据加载前加载 | ||
| - 优化search的加载顺序,在依赖加载完成后再进行加载,避免依赖前加载导致的数据不全的问题 | ||
| ### 4.4.3 | ||
| - feat(depend): 优化依赖相关功能,依赖实现创建时加载和数据加载前加载。 | ||
| - feat(search): 优化 `search` 的加载顺序,在依赖加载完成后再进行加载。 | ||
| ### 4.4.1 | ||
| - 依赖升级,生命周期优化 | ||
| - chore(deps): 依赖升级,生命周期优化。 | ||
| ### 4.3.42/43 | ||
| - 优化triggerMethod相关函数的传参 | ||
| - triggerMethod实现节流 | ||
| ### 4.3.43 | ||
| - refactor(events): 优化 `triggerMethod` 相关函数的传参。 | ||
| - feat(events): `triggerMethod` 实现节流。 | ||
| ### 4.3.41 | ||
| - 添加depth作为可能存在的深度的额外判断条件 | ||
| - feat(data): 添加 `depth` 作为可能存在的深度的额外判断条件。 | ||
| ### 4.3.39/40 | ||
| - DictionaryData/DefaultMod添加collapse折叠判断值 | ||
| ### 4.3.40 | ||
| - feat(mod): `DictionaryData/DefaultMod` 添加 `collapse` 折叠判断值。 | ||
| ### 4.3.37/38 | ||
| - SelectEdit添加search相关设置项 | ||
| ### 4.3.38 | ||
| - feat(select): `SelectEdit` 添加 `search` 相关设置项。 | ||
| ### 4.3.34/35/36 | ||
| - ComplexData的默认函数添加editData,优化函数赋值和类型 | ||
| ### 4.3.36 | ||
| - feat(data): `ComplexData` 的默认函数添加 `editData`,优化函数赋值和类型。 | ||
| ### 4.3.32/33 | ||
| - DefaultEdit的rule相关参数优化 | ||
| ### 4.3.33 | ||
| - refactor(edit): `DefaultEdit` 的 `rule` 相关参数优化。 | ||
| ### 4.3.29/30/31 | ||
| - CustomEdit添加model属性 | ||
| - SearchData优化Button初始化参数 | ||
| ### 4.3.31 | ||
| - feat(custom): `CustomEdit` 添加 `model` 属性。 | ||
| - feat(search): `SearchData` 优化 `Button` 初始化参数。 | ||
| ### 4.3.28 | ||
| - 优化undefined校验 | ||
| - refactor(code): 优化 `undefined` 校验。 | ||
| ### 4.3.20/21/22/23/24/25/26/27 | ||
| - 优化FileEdit组件,统一上传插件的整体逻辑 | ||
| ### 4.3.27 | ||
| - feat(file): 优化 `FileEdit` 组件,统一上传插件的整体逻辑。 | ||
| ### 4.3.16/17/18/19 | ||
| - 日期范围接收endProp字段,直接解析 | ||
| - 添加rangeLimit范围限制,模板根据具体情况解析 | ||
| - 优化fileOption类型 | ||
| ### 4.3.19 | ||
| - feat(date): 日期范围接收 `endProp` 字段,直接解析。 | ||
| - feat(date): 添加 `rangeLimit` 范围限制,模板根据具体情况解析。 | ||
| - refactor(types): 优化 `fileOption` 类型。 | ||
| ### 4.3.15 | ||
| - 统一Cascader名称 | ||
| - refactor(cascader): 统一 `Cascader` 名称。 | ||
| ### 4.3.12/13/14 | ||
| - 优化SelectEdit对SelectData的适配 | ||
| - MenuValue实现防抖参数添加 | ||
| ### 4.3.14 | ||
| - refactor(select): 优化 `SelectEdit` 对 `SelectData` 的适配。 | ||
| - feat(menu): `MenuValue` 实现防抖参数添加。 | ||
| ### 4.3.10/11 | ||
| - 优化SearchData/FormEdit | ||
| ### 4.3.11 | ||
| - refactor(edit): 优化 `SearchData/FormEdit`。 | ||
| ### 4.3.7/8/9 | ||
| - ObserveList添加reset | ||
| - 优化整体逻辑,DictionaryValue.parseValue解析DefaultInfo模块 | ||
| - 修正GridParse整体逻辑 | ||
| ### 4.3.9 | ||
| - feat(observe): `ObserveList` 添加 `reset`。 | ||
| - refactor(dictionary): 优化整体逻辑,`DictionaryValue.parseValue` 解析 `DefaultInfo` 模块。 | ||
| - fix(grid): 修正 `GridParse` 整体逻辑。 | ||
| ### 4.3.4/5/6 | ||
| - 级联表单适配完成,准备测试 | ||
| ### 4.3.6 | ||
| - feat(form): 级联表单适配完成,准备测试。 | ||
| ### 4.3.3 | ||
| - 添加FormEdit | ||
| - DictionaryValue接收添加dictionary(DictionaryData) | ||
| - feat(form): 添加 `FormEdit`。 | ||
| - feat(dictionary): `DictionaryValue` 接收添加 `dictionary(DictionaryData)`。 | ||
| ### 4.3.2 | ||
| - 修正DictionaryValue错误引用 | ||
| - 修正DictionaryValue.parseValue未正确resolve的BUG | ||
| - fix(dictionary): 修正 `DictionaryValue` 错误引用。 | ||
| - fix(dictionary): 修正 `DictionaryValue.parseValue` 未正确 `resolve` 的 BUG。 | ||
| ### 4.3.1 | ||
| - 重点非兼容性更新 | ||
| - 依赖升级,优化setProp/getProp相关逻辑 | ||
| - 添加Symbol('empty')值和nonEmptySetProp/nonEmptySetComplexProp函数,实现当值为Symbol('empty')时不进行赋值和传递 | ||
| - 优化字典赋值格式化相关逻辑 | ||
| - 更改整体逻辑,由之前基于源数据生成新数据后保存更改为源数据直接进行格式化处理后保存,减少添加非展示性字段的对接工作以及忘记对接后的排查工作 | ||
| - 删除DefaultList.auto | ||
| - 删除DefaultEdit.value.init | ||
| - 删除SearchData.$form | ||
| - DictionaryValue赋值默认直接使用setProp赋值,不考虑级联属性a.b的赋值逻辑,减少性能消耗 | ||
| - DictionaryValue | ||
| - - 添加complex.assignProp设置项 | ||
| - - 删除$setTargetData函数 | ||
| - - 添加$assignData函数,基于原$formatData函数,实现赋值相关逻辑 | ||
| - - 更改$formatData函数,由原来的赋值逻辑更改为格式化逻辑 | ||
| - DictionaryData | ||
| - - 添加complex.assign设置项 | ||
| - - createEditData => parseData | ||
| - - createPostData => collectData | ||
| - SearchData | ||
| - - $resetFormData => resetFormData,删除observe重新构建逻辑 | ||
| - - $syncFormData => validateAndSyncData | ||
| - - syncFormData => syncData | ||
| - - resetFormData => resetForm | ||
| - - - resetOption.copy = > resetOption.sync | ||
| - - setForm => assignData | ||
| - ComplexData | ||
| - - createEditDataByDictionary => parseDataByDictionary | ||
| - - createPostDataByDictionary => collectDataByDictionary | ||
| - refactor(data)!: **[重点非兼容性更新]** | ||
| - 依赖升级,优化 `setProp/getProp` 相关逻辑。 | ||
| - 添加 `Symbol('empty')` 值和 `nonEmptySetProp/nonEmptySetComplexProp` 函数,实现当值为 `Symbol('empty')` 时不进行赋值和传递。 | ||
| - 优化字典赋值格式化相关逻辑。 | ||
| - 更改整体逻辑,由之前基于源数据生成新数据后保存更改为源数据直接进行格式化处理后保存。 | ||
| - 删除 `DefaultList.auto`。 | ||
| - 删除 `DefaultEdit.value.init`。 | ||
| - 删除 `SearchData.$form`。 | ||
| - `DictionaryValue` 赋值默认直接使用 `setProp` 赋值,不考虑级联属性 `a.b` 的赋值逻辑。 | ||
| - `DictionaryValue`: | ||
| - 添加 `complex.assignProp` 设置项。 | ||
| - 删除 `$setTargetData` 函数。 | ||
| - 添加 `$assignData` 函数,基于原 `$formatData` 函数,实现赋值相关逻辑。 | ||
| - 更改 `$formatData` 函数,由原来的赋值逻辑更改为格式化逻辑。 | ||
| - `DictionaryData`: | ||
| - 添加 `complex.assign` 设置项。 | ||
| - `createEditData` => `parseData` | ||
| - `createPostData` => `collectData` | ||
| - `SearchData`: | ||
| - `$resetFormData` => `resetFormData`, 删除 `observe` 重新构建逻辑。 | ||
| - `$syncFormData` => `validateAndSyncData` | ||
| - `syncFormData` => `syncData` | ||
| - `resetFormData` => `resetForm` | ||
| - `resetOption.copy` => `resetOption.sync` | ||
| - `setForm` => `assignData` | ||
| - `ComplexData`: | ||
| - `createEditDataByDictionary` => `parseDataByDictionary` | ||
| - `createPostDataByDictionary` => `collectDataByDictionary` | ||
| ### 4.2.23 | ||
| - 依赖升级 | ||
| - 添加DataWithSimpleLoad类型,优化BaseData/SelectData/DefaultLoadEdit类型 | ||
| - 减少unknow 类型 | ||
| - chore(deps): 依赖升级。 | ||
| - refactor(types): 添加 `DataWithSimpleLoad` 类型,优化 `BaseData/SelectData/DefaultLoadEdit` 类型。 | ||
| - refactor(types): 减少 `unknow` 类型。 | ||
| ### 4.2.22 | ||
| - 添加DataWithLoad类型,优化BaseData/SelectData/DefaultLoadEdit类型 | ||
| - 优化RelationData的数据类型要求,扩展适配性 | ||
| - refactor(types): 添加 `DataWithLoad` 类型,优化 `BaseData/SelectData/DefaultLoadEdit` 类型。 | ||
| - refactor(types): 优化 `RelationData` 的数据类型要求,扩展适配性。 | ||
| ### 4.2.21 | ||
| - 修正ModuleData的reset/destory | ||
| - 优化SearchData的reset/destory | ||
| - fix(module): 修正 `ModuleData` 的 `reset/destory`。 | ||
| - fix(search): 优化 `SearchData` 的 `reset/destory`。 | ||
| ### 4.2.20 | ||
| - CascaderData=>SelectData | ||
| - refactor(select): `CascaderData` => `SelectData`。 | ||
| ### 4.2.19 | ||
| - 简化SelectValue设置项,删除dict相关参数直接使用默认值,特殊项目可单独生成SelectValue类适配,减少内存占用 | ||
| - 拆分CascaderValue和SelectValue | ||
| - SelectData=>CascaderData | ||
| - SelectEdit初始化接收SelectValue参数,删除dict相关字段,如需额外操作则提前格式化或者由模板处理 | ||
| - refactor(select): 简化 `SelectValue` 设置项,删除 `dict` 相关参数直接使用默认值。 | ||
| - refactor(select): 拆分 `CascaderValue` 和 `SelectValue`。 | ||
| - refactor(select): `SelectData` => `CascaderData`。 | ||
| - refactor(select): `SelectEdit` 初始化接收 `SelectValue` 参数,删除 `dict` 相关字段。 | ||
| ### 4.2.18 | ||
| - SearchData的getData默认深拷贝,避免在获取数据后改变数据导致问题 | ||
| - 修正SelectData未正确触发创建生命周期的BUG | ||
| - 优化SelectData的storage的加载 | ||
| - Data添加静态函数$formatInitOption格式化加载参数 | ||
| - feat(search): `SearchData` 的 `getData` 默认深拷贝。 | ||
| - fix(select): 修正 `SelectData` 未正确触发创建生命周期的 BUG。 | ||
| - feat(select): 优化 `SelectData` 的 `storage` 的加载。 | ||
| - feat(data): `Data` 添加静态函数 `$formatInitOption` 格式化加载参数。 | ||
| ### 4.2.15/16/17 | ||
| - BaseData的loadDepend整体逻辑优化,避免主数据先于依赖数据加载完成 | ||
| - RelationData类型修正 | ||
| - 依赖升级,未使用参数前缀加_ | ||
| ### 4.2.17 | ||
| - refactor(depend): `BaseData` 的 `loadDepend` 整体逻辑优化,避免主数据先于依赖数据加载完成。 | ||
| - fix(types): `RelationData` 类型修正。 | ||
| - chore(deps): 依赖升级,未使用参数前缀加 `_`。 | ||
| ### 4.2.13/14 | ||
| - ComplexData添加choice相关函数 | ||
| - 依赖升级 | ||
| ### 4.2.14 | ||
| - feat(choice): `ComplexData` 添加 `choice` 相关函数。 | ||
| - chore(deps): 依赖升级。 | ||
| ### 4.2.12 | ||
| - 优化type位置 | ||
| - 修正DictionaryData类型BUG | ||
| - DictionaryData.createPostData适配ObserveList的冻结功能 | ||
| - refactor(types): 优化 `type` 位置。 | ||
| - fix(types): 修正 `DictionaryData` 类型 BUG。 | ||
| - feat(observe): `DictionaryData.createPostData` 适配 `ObserveList` 的冻结功能。 | ||
| ### 4.2.11 | ||
| - SearchData添加Info详情按钮 | ||
| - ComplexData添加refreshData详情接口 | ||
| - feat(search): `SearchData` 添加 `Info` 详情按钮。 | ||
| - feat(data): `ComplexData` 添加 `refreshData` 详情接口。 | ||
| ### 4.2.10 | ||
| - 删除DefaultInfo/DefaultSimpleMod => DefaultMod/DefaultMod=>DefaultInfo,优化编辑数据链,edit作为一个可编辑的info子类实现 | ||
| - refactor(dictionary)!: **[非兼容性更新]** `DefaultInfo/DefaultSimpleMod` => `DefaultMod`, `DefaultMod` => `DefaultInfo`,优化编辑数据链。 | ||
| ### 4.2.8/9 | ||
| - 删除MenuValue/ButtonValue,改为类型 | ||
| - 修正SimpleDateEdit的默认值问题 | ||
| ### 4.2.9 | ||
| - refactor(types): `MenuValue/ButtonValue` 删除,改为类型。 | ||
| - fix(date): 修正 `SimpleDateEdit` 的默认值问题。 | ||
| ### 4.2.7 | ||
| - DateRangeEdit添加endPlaceholder属性 | ||
| - 编辑数据的$defaultPlaceholder函数优化 | ||
| - 优化DictionaryValue属性originProp为可选不赋值 | ||
| - 优化DictionaryValue/DefaultSimpleMod,fetch=>collect | ||
| - feat(date): `DateRangeEdit` 添加 `endPlaceholder` 属性。 | ||
| - refactor(edit): 编辑数据的 `$defaultPlaceholder` 函数优化。 | ||
| - refactor(dictionary): 优化 `DictionaryValue` 属性 `originProp` 为可选不赋值。 | ||
| - refactor(api): 优化 `DictionaryValue/DefaultSimpleMod`,`fetch` => `collect`。 | ||
| ### 4.2.6 | ||
| - 合并Date/DateRange相关功能 | ||
| - refactor(date): 合并 `Date/DateRange` 相关功能。 | ||
| ### 4.2.3/4/5 | ||
| - 优化字典模块,DefaultSimpleMod => DefaultMod,简化DefaultSimpleMod | ||
| - class extends null弃用 | ||
| - 修正生命周期调用BUG | ||
| ### 4.2.5 | ||
| - refactor(dictionary): 优化字典模块,`DefaultSimpleMod` => `DefaultMod`,简化 `DefaultSimpleMod`。 | ||
| - refactor(code): `class extends null` 弃用。 | ||
| - fix(events): 修正生命周期调用 BUG。 | ||
| ### 4.2.2 | ||
| - DefaultSimpleMod弃用InterfaceData结构,简化构建,对于类似数据仅通过initoption的merge实现,适时考虑在DictionaryValue加载时提供一个特殊的默认值作为各个基准默认值,避免在initoption中重复设置 | ||
| - GridParse输出值格式优化 | ||
| - refactor(dictionary): `DefaultSimpleMod` 弃用 `InterfaceData` 结构,简化构建。 | ||
| - refactor(grid): `GridParse` 输出值格式优化。 | ||
| ### 4.2.1 | ||
| - 修复index导出 | ||
| - fix(build): 修复 `index` 导出。 | ||
| ### 4.2.0 | ||
| - 优化函数名称,_为私有属性,理论上不对外使用,$为功能函数,理论上可对外使用,但可能存在更改逻辑的情况 | ||
| - 优化整个按钮相关逻辑,统一调用链 | ||
| - 优化SelectValue,适配级联数据 | ||
| - 添加StorageValue本地缓存数据控制器,持续优化中 | ||
| - 修正DefaultEdit在multiple时默认值为[]导致的引用问题 | ||
| - 布局通过解析器加值实现,基础布局通过解析器解析基础数据,个体设置通过值来解析,实现页面的整体和个体设置 | ||
| - 优化Edit的rule属性整体逻辑 | ||
| - 优化DictionaryValue/DefaultSimpleMod,format=>assign,show/edit=>parse,post=>collect | ||
| - 优化ObserveList的响应式逻辑,仅监控需要的属性,减少性能消耗 | ||
| - Observe添加额外逻辑,实现冻结和解冻,隐藏参与逻辑判断,冻结的不进行逻辑判断,冻结的属性的响应式也不会被触发,由其他属性变更后解冻可触发 | ||
| - 合并select/cascader | ||
| - refactor(code)!: **[核心重构]** | ||
| - 优化函数名称,`_` 为私有属性,`$` 为功能函数。 | ||
| - 优化整个按钮相关逻辑,统一调用链。 | ||
| - 优化 `SelectValue`,适配级联数据。 | ||
| - 添加 `StorageValue` 本地缓存数据控制器。 | ||
| - 修正 `DefaultEdit` 在 `multiple` 时默认值为 `[]` 导致的引用问题。 | ||
| - 布局通过解析器加值实现。 | ||
| - 优化 `Edit` 的 `rule` 属性整体逻辑。 | ||
| - 优化 `DictionaryValue/DefaultSimpleMod`,`format` => `assign`, `show/edit` => `parse`,`post` => `collect`。 | ||
| - 优化 `ObserveList` 的响应式逻辑,仅监控需要的属性。 | ||
| - `Observe` 添加额外逻辑,实现冻结和解冻。 | ||
| - 合并 `select/cascader`。 | ||
| ### 4.1.18 | ||
| - 修正$triggerMethodWithStatus无函数时的状态回滚 | ||
| - fix(events): 修正 `$triggerMethodWithStatus` 无函数时的状态回滚。 | ||
| ### 4.1.15/16/17 | ||
| - ComplexData修正getSize/setSize => getPageSize/setPageSize | ||
| - ButtonGroupEditOption类型修正 | ||
| - Default添加editable判断是否是需要编辑的数据 | ||
| - Status类型优化 | ||
| - 依赖升级 | ||
| ### 4.1.17 | ||
| - refactor(api): `ComplexData` 修正 `getSize/setSize` => `getPageSize/setPageSize`。 | ||
| - fix(types): `ButtonGroupEditOption` 类型修正。 | ||
| - feat(data): `Default` 添加 `editable` 判断是否是需要编辑的数据。 | ||
| - refactor(types): `Status` 类型优化。 | ||
| - chore(deps): 依赖升级。 | ||
| ### 4.1.13/14 | ||
| - EditData添加simple设置项 | ||
| - DefaultMod基类由Data切换为SimpleData,实现extra | ||
| - 优化PureButtonValue类型 | ||
| - 修正错误icon | ||
| ### 4.1.14 | ||
| - feat(edit): `EditData` 添加 `simple` 设置项。 | ||
| - refactor(mod): `DefaultMod` 基类由 `Data` 切换为 `SimpleData`, 实现 `extra`。 | ||
| - refactor(types): 优化 `PureButtonValue` 类型。 | ||
| - fix(icon): 修正错误 `icon`。 | ||
| ### 4.1.12 | ||
| - SearchData的Button提前生成 | ||
| - feat(search): `SearchData` 的 `Button` 提前生成。 | ||
| ### 4.1.11 | ||
| - 优化ButtonValue类型 | ||
| - refactor(types): 优化 `ButtonValue` 类型。 | ||
| ### 4.1.10 | ||
| - 优化SearchData的observe传参 | ||
| - 重要:FormValue由抽象类转换为实体类,避免加载顺序导致的BUG | ||
| - refactor(search): 优化 `SearchData` 的 `observe` 传参。 | ||
| - refactor(form)!: **[重要]** `FormValue` 由抽象类转换为实体类,避免加载顺序导致的 BUG。 | ||
| ### 4.1.9 | ||
| - 优化加载编辑数据逻辑 | ||
| - refactor(edit): 优化加载编辑数据逻辑。 | ||
| ### 4.1.8 | ||
| - 升级依赖 | ||
| - 实现disabledDate相关逻辑 | ||
| - chore(deps): 升级依赖。 | ||
| - feat(date): 实现 `disabledDate` 相关逻辑。 | ||
| ### 4.1.4/5/6/7 | ||
| - 优化检索 | ||
| - 将配置项集成在类静态属性中 | ||
| - 优化文件上传相关参数 | ||
| ### 4.1.7 | ||
| - refactor(search): 优化检索。 | ||
| - refactor(config): 将配置项集成在类静态属性中。 | ||
| - refactor(file): 优化文件上传相关参数。 | ||
| ### 4.1.3 | ||
| - 按钮加载/禁用接收函数 | ||
| - 扩展检索菜单默认值 | ||
| - feat(button): 按钮加载/禁用接收函数。 | ||
| - feat(search): 扩展检索菜单默认值。 | ||
| ### 4.1.2 | ||
| - 优化字典构建函数 | ||
| - 修正检索menu.name被非预期赋值 | ||
| - refactor(dictionary): 优化字典构建函数。 | ||
| - fix(search): 修正检索 `menu.name` 被非预期赋值。 | ||
| ### 4.1.1 | ||
| - 修正BaseData的triggerMethod相关逻辑BUG | ||
| - 优化检索函数的菜单默认为独立模块 | ||
| - fix(events): 修正 `BaseData` 的 `triggerMethod` 相关逻辑 BUG。 | ||
| - refactor(search): 优化检索函数的菜单默认为独立模块。 | ||
| ### 4.1.0 | ||
| - 优化函数命名规则:外部函数以字母开头,内部函数以$开头,私有函数以_开头 | ||
| - refactor(code): 优化函数命名规则:外部函数以字母开头,内部函数以 `$` 开头,私有函数以 `_` 开头。 | ||
| ### 4.0.20 | ||
| - 优化创建生命周期函数,通过$onCreatedLife实现生命周期创建完成回调 | ||
| - feat(events): 优化创建生命周期函数,通过 `$onCreatedLife` 实现生命周期创建完成回调。 | ||
| ### 4.0.18/19 | ||
| - SearchData菜单默认参数优化 | ||
| - config添加formatPixel函数 | ||
| - ButtonGroupEdit添加间隔设置项 | ||
| ### 4.0.19 | ||
| - refactor(search): `SearchData` 菜单默认参数优化。 | ||
| - feat(config): `config` 添加 `formatPixel` 函数。 | ||
| - feat(button): `ButtonGroupEdit` 添加间隔设置项。 | ||
| ### 4.0.17 | ||
| - 非兼容性更新:DependData=>RelationData,位置由ModuleData转换为BaseData的不可枚举属性 | ||
| - 简化依赖相关函数,删除once等设置项,改为bind函数中传递解绑函数 | ||
| - refactor(depend)!: **[非兼容性更新]** `DependData` => `RelationData`,位置由 `ModuleData` 转换为 `BaseData` 的不可枚举属性。 | ||
| - refactor(depend): 简化依赖相关函数,删除 `once` 等设置项,改为 `bind` 函数中传递解绑函数。 | ||
| ### 4.0.15/16 | ||
| - 非兼容性更新:DictionaryData:$createEditData=>$createEditData,后续相关调用名称优化 | ||
| - 实现DateEdit/DateRangeEdit的数据转换 | ||
| - 扩展ComplexData的常用函数,减少后期自定义类 | ||
| ### 4.0.16 | ||
| - refactor(api)!: **[非兼容性更新]** `DictionaryData:$createEditData` => `$createEditData`,后续相关调用名称优化。 | ||
| - feat(date): 实现 `DateEdit/DateRangeEdit` 的数据转换。 | ||
| - feat(data): 扩展 `ComplexData` 的常用函数,减少后期自定义类。 | ||
| ### 4.0.14 | ||
| - 优化字段加载和文件目录,修正组件构建BUG | ||
| - refactor(build): 优化字段加载和文件目录,修正组件构建 BUG。 | ||
| ### 4.0.13 | ||
| - 升级依赖,适配formatConfig | ||
| - chore(deps): 升级依赖,适配 `formatConfig`。 | ||
| ### 4.0.12 | ||
| - BUG:修正DefaultMod相关类的初始化未正确传递parent的BUG | ||
| - BUG:修正SelectValue的初始化类型中dict错误的被标记为必填项的BUG | ||
| - fix(mod): 修正 `DefaultMod` 相关类的初始化未正确传递 `parent` 的 BUG。 | ||
| - fix(select): 修正 `SelectValue` 的初始化类型中 `dict` 错误的被标记为必填项的 BUG。 | ||
| ### 4.0.10/11 | ||
| - 添加基础的Data构建格式化函数,适配不同环境 | ||
| - 升级依赖,修正类型报错 | ||
| ### 4.0.11 | ||
| - feat(data): 添加基础的 `Data` 构建格式化函数,适配不同环境。 | ||
| - chore(deps): 升级依赖,修正类型报错。 | ||
| ### 4.0.9 | ||
| - 优化AttrsValue/ContentEdit/DateEdit/DateRangeEdit | ||
| - refactor(edit): 优化 `AttrsValue/ContentEdit/DateEdit/DateRangeEdit`。 | ||
| ### 4.0.8 | ||
| - 非兼容性更新:添加LayoutValue/InterfaceLayoutValue,优化组件的width到$layout中 | ||
| - 修正DefaultDate=>DateEdit. | ||
| - 添加DateRangeEdit | ||
| - 升级依赖 | ||
| - refactor(layout)!: **[非兼容性更新]** 添加 `LayoutValue/InterfaceLayoutValue`,优化组件的 `width` 到 `$layout` 中。 | ||
| - refactor(date): 修正 `DefaultDate` => `DateEdit`. | ||
| - feat(date): 添加 `DateRangeEdit`。 | ||
| - chore(deps): 升级依赖。 | ||
| ### 4.0.4/5/6/7 | ||
| - 非兼容性更新: AttributeValue => AttrsValue | ||
| - 统一$local/$attrs属性 | ||
| ### 4.0.7 | ||
| - refactor(attrs)!: **[非兼容性更新]** `AttributeValue` => `AttrsValue`。 | ||
| - refactor(attrs): 统一 `$local/$attrs` 属性。 | ||
| ### 4.0.2/3 | ||
| - 优化Attribute/Render相关逻辑 | ||
| ### 4.0.3 | ||
| - refactor(render): 优化 `Attribute/Render` 相关逻辑。 | ||
| ### 4.0.1 | ||
| - 基于complex-data简化逻辑,实现基本的功能 | ||
| - feat: 基于 `complex-data` 简化逻辑,实现基本的功能。 |
+7
-4
| { | ||
| "name": "complex-data", | ||
| "version": "4.9.8", | ||
| "version": "4.10.1", | ||
| "description": "a complex data", | ||
@@ -13,9 +13,12 @@ "type": "module", | ||
| "check": "tsc --noEmit", | ||
| "test": "echo \"Error: no test specified\" && exit 1" | ||
| "test": "vitest", | ||
| "coverage": "vitest run --coverage" | ||
| }, | ||
| "dependencies": { | ||
| "complex-utils": "2.9.1 - 2.9.99" | ||
| "complex-utils": "2.10.2 - 2.10.99" | ||
| }, | ||
| "devDependencies": { | ||
| "typescript": "^5.2.2" | ||
| "jsdom": "^27.1.0", | ||
| "typescript": "^5.2.2", | ||
| "vitest": "^4.0.6" | ||
| }, | ||
@@ -22,0 +25,0 @@ "keywords": [ |
@@ -25,3 +25,5 @@ import { DefaultBufferType } from "../data/DefaultData" | ||
| this.$list = this.createListByDictionary(originList, originFrom, useSetData) as D[] | ||
| this.setPageCount(totalNum!) | ||
| if (totalNum !== undefined) { | ||
| this.setPageCount(totalNum) | ||
| } | ||
| this._syncData(true, 'formatList') | ||
@@ -33,3 +35,6 @@ } | ||
| } | ||
| return this.$list.find(item => item[prop!] == data) | ||
| if (!prop) { | ||
| return | ||
| } | ||
| return this.$list.find(item => item[prop] === data) | ||
| } | ||
@@ -36,0 +41,0 @@ getValueIndex(item: D) { |
+43
-87
@@ -147,15 +147,15 @@ import BaseData, { BaseDataInitOption, loadFunctionType } from "./BaseData" | ||
| startUpdate(...args: Parameters<UpdateData['start']>) { | ||
| return this.$module.update!.start(...args) | ||
| return this.$module.update?.start(...args) | ||
| } | ||
| updateImmerdiate(...args: Parameters<UpdateData['immerdiate']>) { | ||
| return this.$module.update!.immerdiate(...args) | ||
| return this.$module.update?.immerdiate(...args) | ||
| } | ||
| clearUpdate(...args: Parameters<UpdateData['clear']>) { | ||
| return this.$module.update!.clear(...args) | ||
| return this.$module.update?.clear(...args) | ||
| } | ||
| resetUpdate(...args: Parameters<UpdateData['reset']>) { | ||
| return this.$module.update!.reset(...args) | ||
| return this.$module.update?.reset(...args) | ||
| } | ||
| destroyUpdate(...args: Parameters<UpdateData['destroy']>) { | ||
| return this.$module.update!.destroy(...args) | ||
| return this.$module.update?.destroy(...args) | ||
| } | ||
@@ -204,25 +204,15 @@ protected _triggerUpdateData (...args: unknown[]) { | ||
| getChoiceData(...args: Parameters<ChoiceData['getData']>) { | ||
| if (this.$module.choice) { | ||
| return this.$module.choice.getData(...args) | ||
| } | ||
| return this.$module.choice?.getData(...args) | ||
| } | ||
| getChoiceId(...args: Parameters<ChoiceData['getId']>) { | ||
| if (this.$module.choice) { | ||
| return this.$module.choice.getId(...args) | ||
| } | ||
| return this.$module.choice?.getId(...args) | ||
| } | ||
| getChoiceList(...args: Parameters<ChoiceData['getList']>) { | ||
| if (this.$module.choice) { | ||
| return this.$module.choice.getList(...args) | ||
| } | ||
| return this.$module.choice?.getList(...args) | ||
| } | ||
| setChoice(...args: Parameters<ChoiceData['setData']>) { | ||
| if (this.$module.choice) { | ||
| return this.$module.choice.setData(...args) | ||
| } | ||
| return this.$module.choice?.setData(...args) | ||
| } | ||
| resetChoice(...args: Parameters<ChoiceData['reset']>) { | ||
| if (this.$module.choice) { | ||
| return this.$module.choice.reset(...args) | ||
| } | ||
| return this.$module.choice?.reset(...args) | ||
| } | ||
@@ -232,25 +222,15 @@ /* --- choice end --- */ | ||
| setSortData(...args: Parameters<SortData['setData']>) { | ||
| if (this.$module.sort) { | ||
| return this.$module.sort.setData(...args) | ||
| } | ||
| return this.$module.sort?.setData(...args) | ||
| } | ||
| getSortData(...args: Parameters<SortData['getData']>) { | ||
| if (this.$module.sort) { | ||
| return this.$module.sort.getData(...args) | ||
| } | ||
| return this.$module.sort?.getData(...args) | ||
| } | ||
| getSortValue(...args: Parameters<SortData['getValue']>) { | ||
| if (this.$module.sort) { | ||
| return this.$module.sort.getValue(...args) | ||
| } | ||
| return this.$module.sort?.getValue(...args) | ||
| } | ||
| getSortOrder(...args: Parameters<SortData['getOrder']>) { | ||
| if (this.$module.sort) { | ||
| return this.$module.sort.getOrder(...args) | ||
| } | ||
| return this.$module.sort?.getOrder(...args) | ||
| } | ||
| resetSort(...args: Parameters<SortData['reset']>) { | ||
| if (this.$module.sort) { | ||
| return this.$module.sort.reset(...args) | ||
| } | ||
| return this.$module.sort?.reset(...args) | ||
| } | ||
@@ -260,50 +240,30 @@ /* --- sort end --- */ | ||
| setPageCount(...args: Parameters<PaginationData['setCount']>) { | ||
| if (this.$module.pagination) { | ||
| return this.$module.pagination.setCount(...args) | ||
| } | ||
| return this.$module.pagination?.setCount(...args) | ||
| } | ||
| getPageCount(...args: Parameters<PaginationData['getCount']>) { | ||
| if (this.$module.pagination) { | ||
| return this.$module.pagination.getCount(...args) | ||
| } | ||
| return this.$module.pagination?.getCount(...args) | ||
| } | ||
| getTotalPage(...args: Parameters<PaginationData['getTotal']>) { | ||
| if (this.$module.pagination) { | ||
| return this.$module.pagination.getTotal(...args) | ||
| } | ||
| return this.$module.pagination?.getTotal(...args) | ||
| } | ||
| setPage(...args: Parameters<PaginationData['setPage']>) { | ||
| if (this.$module.pagination) { | ||
| return this.$module.pagination.setPage(...args) | ||
| } | ||
| return this.$module.pagination?.setPage(...args) | ||
| } | ||
| getPage(...args: Parameters<PaginationData['getPage']>) { | ||
| if (this.$module.pagination) { | ||
| return this.$module.pagination.getPage(...args) | ||
| } | ||
| return this.$module.pagination?.getPage(...args) | ||
| } | ||
| setPageSize(...args: Parameters<PaginationData['setSize']>) { | ||
| if (this.$module.pagination) { | ||
| return this.$module.pagination.setSize(...args) | ||
| } | ||
| return this.$module.pagination?.setSize(...args) | ||
| } | ||
| getPageSize(...args: Parameters<PaginationData['getSize']>) { | ||
| if (this.$module.pagination) { | ||
| return this.$module.pagination.getSize(...args) | ||
| } | ||
| return this.$module.pagination?.getSize(...args) | ||
| } | ||
| setPageAndSize(...args: Parameters<PaginationData['setPageAndSize']>) { | ||
| if (this.$module.pagination) { | ||
| this.$module.pagination.setPageAndSize(...args) | ||
| } | ||
| this.$module.pagination?.setPageAndSize(...args) | ||
| } | ||
| resetPagination(option?: boolean) { | ||
| if (this.$module.pagination) { | ||
| this.$module.pagination.reset(option) | ||
| } | ||
| this.$module.pagination?.reset(option) | ||
| } | ||
| destroyPagination(option?: boolean) { | ||
| if (this.$module.pagination) { | ||
| this.$module.pagination.destroy(option) | ||
| } | ||
| this.$module.pagination?.destroy(option) | ||
| } | ||
@@ -314,45 +274,45 @@ /* --- pagination end --- */ | ||
| updateDictionary (...args: Parameters<DictionaryData['updateDictionary']>) { | ||
| this.$module.dictionary!.updateDictionary(...args) | ||
| this.$module.dictionary?.updateDictionary(...args) | ||
| this._syncData(true, 'updateDictionary') | ||
| } | ||
| getDictionaryValue (...args: Parameters<DictionaryData['getValue']>) { | ||
| return this.$module.dictionary!.getValue(...args) | ||
| return this.$module.dictionary?.getValue(...args) | ||
| } | ||
| setDictionaryProp (...args: Parameters<DictionaryData['setProp']>) { | ||
| this.$module.dictionary!.setProp(...args) | ||
| this.$module.dictionary?.setProp(...args) | ||
| this._syncData(true, 'setDictionaryProp') | ||
| } | ||
| getDictionaryProp (...args: Parameters<DictionaryData['getProp']>) { | ||
| return this.$module.dictionary!.getProp(...args) | ||
| return this.$module.dictionary?.getProp(...args) | ||
| } | ||
| setDictionaryPropValue (...args: Parameters<DictionaryData['setPropValue']>) { | ||
| this.$module.dictionary!.setPropValue(...args) | ||
| this.$module.dictionary?.setPropValue(...args) | ||
| this._syncData(true, 'setDictionaryPropValue') | ||
| } | ||
| getDictionaryPropValue (...args: Parameters<DictionaryData['getPropValue']>) { | ||
| return this.$module.dictionary!.getPropValue(...args) | ||
| return this.$module.dictionary?.getPropValue(...args) | ||
| } | ||
| createListByDictionary (...args: Parameters<DictionaryData['createList']>) { | ||
| return this.$module.dictionary!.createList(...args) | ||
| return this.$module.dictionary?.createList(...args) | ||
| } | ||
| createDataByDictionary (...args: Parameters<DictionaryData['createData']>) { | ||
| return this.$module.dictionary!.createData(...args) | ||
| return this.$module.dictionary?.createData(...args) | ||
| } | ||
| updateDataByDictionary (...args: Parameters<DictionaryData['updateData']>) { | ||
| return this.$module.dictionary!.updateData(...args) | ||
| return this.$module.dictionary?.updateData(...args) | ||
| } | ||
| getDictionaryList (...args: Parameters<DictionaryData['getList']>) { | ||
| return this.$module.dictionary!.getList(...args) | ||
| return this.$module.dictionary?.getList(...args) | ||
| } | ||
| getDictionaryPageList (...args: Parameters<DictionaryData['getPageList']>) { | ||
| return this.$module.dictionary!.getPageList(...args) | ||
| return this.$module.dictionary?.getPageList(...args) | ||
| } | ||
| getDictionaryObserveList (...args: Parameters<DictionaryData['getObserveList']>) { | ||
| return this.$module.dictionary!.getObserveList(...args) | ||
| return this.$module.dictionary?.getObserveList(...args) | ||
| } | ||
| parseDataByDictionary (...args: Parameters<DictionaryData['parseData']>) { | ||
| return this.$module.dictionary!.parseData(...args) | ||
| return this.$module.dictionary?.parseData(...args) | ||
| } | ||
| collectDataByDictionary (...args: Parameters<DictionaryData['collectData']>) { | ||
| return this.$module.dictionary!.collectData(...args) | ||
| return this.$module.dictionary?.collectData(...args) | ||
| } | ||
@@ -362,10 +322,6 @@ /* --- dictionary end --- */ | ||
| assignSearch(...args: Parameters<SearchData['assignData']>) { | ||
| return this.$module.search!.assignData(...args) | ||
| return this.$module.search?.assignData(...args) | ||
| } | ||
| getSearch(...args: Parameters<SearchData['getData']>) { | ||
| if (this.$module.search) { | ||
| return this.$module.search.getData(...args) | ||
| } else { | ||
| return {} | ||
| } | ||
| return this.$module.search?.getData(...args) || {} | ||
| } | ||
@@ -375,3 +331,3 @@ setSearch(action = 'set') { | ||
| this.triggerLife('beforeSearch', this, action) | ||
| this.$module.search!.validateAndSyncData().then(() => { | ||
| this.$module.search?.validateAndSyncData().then(() => { | ||
| this.reloadData({ | ||
@@ -401,3 +357,3 @@ data: true, | ||
| resetSearch(option?: resetOption) { | ||
| this.$module.search!.resetForm('reset', option) | ||
| this.$module.search?.resetForm('reset', option) | ||
| return this.setSearch('reset') | ||
@@ -404,0 +360,0 @@ } |
+83
-12
@@ -11,2 +11,6 @@ export interface ArrayValueDataType { | ||
| $frozen: Map<PropertyKey, D> // 冻结数据 | ||
| /** | ||
| * 构造函数 | ||
| * @param {D[]} list - 初始数据列表 | ||
| */ | ||
| constructor(list?: D[]) { | ||
@@ -22,3 +26,9 @@ this.$map = new Map() | ||
| } | ||
| protected _showByIndex(target: D, targetIndex: number) { | ||
| /** | ||
| * 根据在完整列表($prop)中的位置,将一个项目插入到可见列表(data)的正确位置 | ||
| * @param {D} target - 目标项目 | ||
| * @param {number} targetIndex - 目标项目在 $prop 数组中的索引 | ||
| * @returns {number} 插入后在 data 数组中的索引 | ||
| */ | ||
| protected _insertItemByIndex(target: D, targetIndex: number) { | ||
| let preIndex = -1 | ||
@@ -36,8 +46,23 @@ for (let index = targetIndex - 1; index >= 0; index--) { | ||
| } | ||
| /** | ||
| * 检查项目是否被隐藏 | ||
| * @param {PropertyKey} prop - 项目的 $prop | ||
| * @returns {boolean} | ||
| */ | ||
| isHide(prop: PropertyKey) { | ||
| return this.$hidden.has(prop) | ||
| } | ||
| /** | ||
| * 检查项目是否被冻结 | ||
| * @param {PropertyKey} prop - 项目的 $prop | ||
| * @returns {boolean} | ||
| */ | ||
| isFrozen(prop: PropertyKey) { | ||
| return this.$frozen.has(prop) | ||
| } | ||
| /** | ||
| * 获取项目的状态 ('show', 'hide', 'frozen', '') | ||
| * @param {PropertyKey} prop - 项目的 $prop | ||
| * @returns {('show' | 'hide' | 'frozen' | '')} | ||
| */ | ||
| getStatus(prop: PropertyKey) { | ||
@@ -54,2 +79,6 @@ if (this.isHide(prop)) { | ||
| } | ||
| /** | ||
| * 在列表末尾添加一个新项目 | ||
| * @param {D} value - 要添加的项目 | ||
| */ | ||
| push(value: D) { | ||
@@ -60,2 +89,6 @@ this.data.push(value) | ||
| } | ||
| /** | ||
| * 在列表开头添加一个新项目 | ||
| * @param {D} target - 要添加的项目 | ||
| */ | ||
| unshift(target: D) { | ||
@@ -66,2 +99,6 @@ this.data.unshift(target) | ||
| } | ||
| /** | ||
| * 从列表末尾移除一个项目 | ||
| * @returns {D | undefined} 被移除的项目 | ||
| */ | ||
| pop() { | ||
@@ -79,2 +116,6 @@ const value = this.data.pop() | ||
| } | ||
| /** | ||
| * 从列表开头移除一个项目 | ||
| * @returns {D | undefined} 被移除的项目 | ||
| */ | ||
| shift() { | ||
@@ -92,6 +133,15 @@ const value = this.data.shift() | ||
| } | ||
| /** | ||
| * 通过 $prop 获取一个项目 | ||
| * @param {PropertyKey} prop - 项目的 $prop | ||
| * @returns {D | undefined} | ||
| */ | ||
| get(prop: PropertyKey) { | ||
| return this.$map.get(prop) | ||
| } | ||
| // 删除 | ||
| /** | ||
| * 通过 $prop 删除一个项目 | ||
| * @param {PropertyKey} prop - 项目的 $prop | ||
| * @returns {D | undefined} 被删除的项目 | ||
| */ | ||
| delete(prop: PropertyKey) { | ||
@@ -112,13 +162,25 @@ const value = this.get(prop) | ||
| } | ||
| // 基于实际index插入 | ||
| /** | ||
| * 在指定索引处插入一个新项目 | ||
| * @param {D} value - 要插入的项目 | ||
| * @param {number} index - 要插入的索引位置 | ||
| * @warning [严重 Bug] 此方法存在严重错误,splice的第三个参数应为 value.$prop,而不是数字 1。 | ||
| */ | ||
| pushByIndex(value: D, index: number) { | ||
| this.$prop.splice(index, 0, 1) | ||
| this.$prop.splice(index, 0, value.$prop) | ||
| this.$map.set(value.$prop, value) | ||
| this._showByIndex(value, index) | ||
| this._insertItemByIndex(value, index) | ||
| } | ||
| // 获取实际index | ||
| /** | ||
| * 获取项目在完整列表($prop)中的索引 | ||
| * @param {PropertyKey} prop - 项目的 $prop | ||
| * @returns {number} | ||
| */ | ||
| getIndex(prop: PropertyKey) { | ||
| return this.$prop.indexOf(prop) | ||
| } | ||
| // 隐藏 | ||
| /** | ||
| * 隐藏一个项目 | ||
| * @param {PropertyKey} prop - 要隐藏的项目的 $prop | ||
| */ | ||
| hide(prop: PropertyKey) { | ||
@@ -132,3 +194,6 @@ if (this.getStatus(prop) === 'show') { | ||
| } | ||
| // 显示 | ||
| /** | ||
| * 显示一个被隐藏的项目 | ||
| * @param {PropertyKey} prop - 要显示的项目的 $prop | ||
| */ | ||
| show(prop: PropertyKey) { | ||
@@ -140,7 +205,10 @@ if (this.isHide(prop)) { | ||
| const index = this.getIndex(prop) | ||
| this._showByIndex(value, index) | ||
| this._insertItemByIndex(value, index) | ||
| } | ||
| } | ||
| } | ||
| // 冻结 | ||
| /** | ||
| * 冻结一个项目 | ||
| * @param {PropertyKey} prop - 要冻结的项目的 $prop | ||
| */ | ||
| freeze(prop: PropertyKey) { | ||
@@ -154,3 +222,6 @@ if (this.getStatus(prop) === 'show') { | ||
| } | ||
| // 解冻 | ||
| /** | ||
| * 解冻一个项目 | ||
| * @param {PropertyKey} prop - 要解冻的项目的 $prop | ||
| */ | ||
| thaw(prop: PropertyKey) { | ||
@@ -162,3 +233,3 @@ if (this.isFrozen(prop)) { | ||
| const index = this.getIndex(prop) | ||
| this._showByIndex(value, index) | ||
| this._insertItemByIndex(value, index) | ||
| } | ||
@@ -165,0 +236,0 @@ } |
@@ -65,9 +65,8 @@ import SelectValue, { SelectValueInitOption, SelectValueType, checkItem, filterType, getFilter } from "./SelectValue" | ||
| if (filter(item)) { | ||
| const children = item[this.cascader!] as undefined | D[] | ||
| const currentItem = { ...item } as CascaderValueType<NonNullable<C>> | ||
| const children = currentItem[this.cascader!] as undefined | D[] | ||
| if (children && children.length > 0) { | ||
| const currentItem = { ...item } as CascaderValueType<NonNullable<C>> | ||
| currentItem[this.cascader as NonNullable<C>] = this._filterCascaderList(filter, children as D[]) as CascaderValueType<NonNullable<C>>[] | ||
| } else { | ||
| currentList.push(item) | ||
| (currentItem as any)[this.cascader!] = this._filterCascaderList(filter, children) | ||
| } | ||
| currentList.push(currentItem as D) | ||
| } | ||
@@ -74,0 +73,0 @@ }) |
+12
-3
@@ -41,2 +41,8 @@ | ||
| /** | ||
| * 栅格布局计算类 | ||
| * 核心思想:基于“一行总24栅格”的原则,根据一行计划排列的元素总数(line), | ||
| * 以及所有元素的label和content计划占用的总栅格数, | ||
| * 计算出单个元素的label、content和offset各应占多少栅格。 | ||
| */ | ||
| class GridParse { | ||
@@ -51,3 +57,2 @@ static $name = 'GridParse' | ||
| label: number | ||
| content: number | ||
| _offset: number | ||
@@ -60,5 +65,8 @@ _default: GridMainValue | ||
| this.line = initOption.line | ||
| // 核心计算1:计算单个元素的左侧间距(offset) | ||
| // 原理:(总宽度24 - 所有label总宽度 - 所有content总宽度) / 元素个数 | ||
| this._offset = (24 - initOption.label - initOption.content) / initOption.line | ||
| // 核心计算2:计算单个元素的label宽度 | ||
| // 原理:所有label总宽度 / 元素个数 | ||
| this.label = initOption.label / initOption.line | ||
| this.content = 24 - this.label - this._offset | ||
| this._default = { | ||
@@ -77,2 +85,3 @@ main: { span: this.getMain(this.line) }, | ||
| getContent(line: number) { | ||
| // 实时计算所有content的总宽度 | ||
| return 24 - this.getLabel(line) - this._offset * line | ||
@@ -99,2 +108,2 @@ } | ||
| export default GridParse | ||
| export default GridParse |
@@ -100,3 +100,3 @@ import { exportMsg, getRandomNum, storage } from 'complex-utils' | ||
| sync(storageData: storageDataType) { | ||
| storageData.time++ | ||
| storageData.num++ | ||
| return storage.setData(this.prop, storageData) | ||
@@ -103,0 +103,0 @@ } |
@@ -75,4 +75,4 @@ import BaseData from '../data/BaseData' | ||
| target.$onCreatedLife('BaseDataCreated', () => { | ||
| if (target.$module && target.$module.dictionary) { | ||
| this.idProp = target.$module.dictionary.getProp('id') | ||
| if (target.$module?.dictionary) { | ||
| this.idProp = target.$module.dictionary.getProp('id') || 'id' | ||
| } | ||
@@ -79,0 +79,0 @@ }) |
@@ -263,3 +263,3 @@ import { Life } from "complex-utils" | ||
| getProp(prop: propDataKeys = 'id') { | ||
| return this.$propData![prop].prop | ||
| return this.$propData?.[prop].prop | ||
| } | ||
@@ -271,3 +271,3 @@ setPropValue(value: unknown, prop: propDataKeys = 'id') { | ||
| getPropValue(prop: propDataKeys = 'id') { | ||
| return this.$propData![prop].value | ||
| return this.$propData?.[prop].value | ||
| } | ||
@@ -274,0 +274,0 @@ getValue(prop: string) { |
@@ -92,3 +92,3 @@ import { deepCloneData, getType } from "complex-utils" | ||
| option: { | ||
| type: 'primay', | ||
| type: 'primary', | ||
| name: '详情', | ||
@@ -95,0 +95,0 @@ icon: 'info', |
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
281750
4.04%67
4.69%6978
0.97%1
-50%1
-50%100
Infinity%3
200%+ Added
- Removed