@robot-admin/naive-ui-components 0.17.0 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +12 -11
  3. package/README_EN.md +1 -0
  4. package/dist/C_AntV2.cjs +1 -1
  5. package/dist/C_AntV2.js +3 -3
  6. package/dist/C_Barcode.css +6 -6
  7. package/dist/C_Barcode2.cjs +1 -1
  8. package/dist/C_Barcode2.js +1 -1
  9. package/dist/C_Chat.css +269 -185
  10. package/dist/C_Chat2.cjs +1 -1
  11. package/dist/C_Chat2.js +1 -1
  12. package/dist/C_Code.css +26 -26
  13. package/dist/C_Code2.cjs +1 -1
  14. package/dist/C_Code2.js +1 -1
  15. package/dist/C_Draggable2.cjs +1 -1
  16. package/dist/C_Draggable2.js +1 -1
  17. package/dist/C_FilePreview.css +96 -57
  18. package/dist/C_FilePreview2.cjs +1 -1
  19. package/dist/C_FilePreview2.js +1 -1
  20. package/dist/C_GlobalSearch.css +140 -118
  21. package/dist/C_GlobalSearch2.cjs +1 -1
  22. package/dist/C_GlobalSearch2.js +1 -1
  23. package/dist/C_ImageCropper.css +10 -10
  24. package/dist/C_ImageCropper2.cjs +1 -1
  25. package/dist/C_ImageCropper2.js +1 -1
  26. package/dist/C_Login.css +79 -79
  27. package/dist/C_Login2.cjs +1 -1
  28. package/dist/C_Login2.js +1 -1
  29. package/dist/C_Map.css +10 -10
  30. package/dist/C_Map2.cjs +1 -1
  31. package/dist/C_Map2.js +1 -1
  32. package/dist/C_OrgChart.css +28 -4
  33. package/dist/C_OrgChart2.cjs +1 -1
  34. package/dist/C_OrgChart2.js +1 -1
  35. package/dist/C_QRCode2.cjs +1 -1
  36. package/dist/C_QRCode2.js +1 -1
  37. package/dist/C_Signature.css +15 -15
  38. package/dist/C_Signature2.cjs +1 -1
  39. package/dist/C_Signature2.js +1 -1
  40. package/dist/C_SplitPane.cjs +1 -1
  41. package/dist/C_SplitPane.css +231 -77
  42. package/dist/C_SplitPane.js +1 -1
  43. package/dist/C_SplitPane2.cjs +1 -1
  44. package/dist/C_SplitPane2.js +1 -1
  45. package/dist/C_Table.base.css +110 -117
  46. package/dist/C_Table.css +110 -117
  47. package/dist/C_Table.d.ts +1 -0
  48. package/dist/C_TagsView2.cjs +1 -1
  49. package/dist/C_TagsView2.js +1 -1
  50. package/dist/C_Transfer.css +93 -84
  51. package/dist/C_Transfer2.cjs +1 -1
  52. package/dist/C_Transfer2.js +1 -1
  53. package/dist/C_Tree.d.ts +1 -0
  54. package/dist/C_Upload.css +5 -5
  55. package/dist/C_Upload2.cjs +1 -1
  56. package/dist/C_Upload2.js +1 -1
  57. package/dist/C_VideoPlayer2.cjs +4 -3
  58. package/dist/C_VideoPlayer2.js +4 -3
  59. package/dist/C_VtableGantt.css +29 -28
  60. package/dist/C_VtableGantt2.cjs +1 -1
  61. package/dist/C_VtableGantt2.js +1 -1
  62. package/dist/C_WaterFall.css +29 -29
  63. package/dist/C_WaterFall2.cjs +1 -1
  64. package/dist/C_WaterFall2.js +1 -1
  65. package/dist/C_WorkFlow2.cjs +1 -1
  66. package/dist/C_WorkFlow2.js +1 -1
  67. package/dist/constants.d.cts +2 -2
  68. package/dist/constants.d.ts +2 -2
  69. package/dist/constants2.d.cts +2 -2
  70. package/dist/constants2.d.ts +2 -2
  71. package/dist/constants3.d.cts +2 -2
  72. package/dist/constants3.d.ts +2 -2
  73. package/dist/constants4.d.cts +5 -5
  74. package/dist/constants4.d.ts +5 -5
  75. package/dist/constants5.d.cts +5 -9
  76. package/dist/constants5.d.ts +5 -9
  77. package/dist/data.d.cts +11 -11
  78. package/dist/data.d.ts +11 -11
  79. package/dist/helpers.cjs +1 -1
  80. package/dist/helpers.js +1 -1
  81. package/dist/index.d.ts +1 -0
  82. package/dist/index.vue.d.cts +6 -6
  83. package/dist/index.vue.d.ts +6 -6
  84. package/dist/index10.vue.d.cts +3 -3
  85. package/dist/index10.vue.d.ts +3 -3
  86. package/dist/index11.vue.d.cts +3 -3
  87. package/dist/index11.vue.d.ts +3 -3
  88. package/dist/index12.vue.d.cts +3 -3
  89. package/dist/index12.vue.d.ts +2 -2
  90. package/dist/index13.vue.d.cts +2 -2
  91. package/dist/index13.vue.d.ts +5 -5
  92. package/dist/index14.vue.d.cts +5 -5
  93. package/dist/index14.vue.d.ts +4 -4
  94. package/dist/index15.vue.d.cts +4 -4
  95. package/dist/index15.vue.d.ts +3 -3
  96. package/dist/index16.vue.d.cts +3 -3
  97. package/dist/index17.vue.d.ts +2 -2
  98. package/dist/index18.vue.d.cts +2 -2
  99. package/dist/index18.vue.d.ts +6 -6
  100. package/dist/index19.vue.d.cts +6 -6
  101. package/dist/index19.vue.d.ts +3 -3
  102. package/dist/index2.vue.d.cts +2 -2
  103. package/dist/index2.vue.d.ts +2 -2
  104. package/dist/index20.vue.d.cts +5 -1
  105. package/dist/index20.vue.d.ts +5 -1
  106. package/dist/index21.vue.d.cts +2 -2
  107. package/dist/index21.vue.d.ts +2 -2
  108. package/dist/index22.vue.d.cts +2 -2
  109. package/dist/index22.vue.d.ts +2 -2
  110. package/dist/index23.vue.d.cts +2 -2
  111. package/dist/index23.vue.d.ts +2 -2
  112. package/dist/index25.vue.d.cts +6 -6
  113. package/dist/index25.vue.d.ts +6 -6
  114. package/dist/index27.vue.d.cts +2 -2
  115. package/dist/index27.vue.d.ts +2 -2
  116. package/dist/index28.vue.d.cts +6 -2
  117. package/dist/index28.vue.d.ts +6 -2
  118. package/dist/index3.vue.d.cts +3 -3
  119. package/dist/index3.vue.d.ts +3 -3
  120. package/dist/index4.vue.d.cts +3 -3
  121. package/dist/index5.vue.d.ts +2 -2
  122. package/dist/index6.vue.d.cts +2 -2
  123. package/dist/index6.vue.d.ts +7 -4
  124. package/dist/index7.vue.d.cts +7 -4
  125. package/dist/index7.vue.d.ts +2 -2
  126. package/dist/index8.vue.d.cts +2 -2
  127. package/dist/index8.vue.d.ts +5 -7
  128. package/dist/index9.vue.d.cts +5 -7
  129. package/dist/index9.vue.d.ts +3 -3
  130. package/dist/mapUtils.d.cts +3 -3
  131. package/dist/mapUtils.d.ts +3 -3
  132. package/dist/presets.d.cts +1 -1
  133. package/dist/presets.d.ts +1 -1
  134. package/dist/style.css +1176 -850
  135. package/dist/useCalendarEvents.d.cts +1 -1
  136. package/dist/useCalendarEvents.d.ts +1 -1
  137. package/dist/useCollapsePanel.d.cts +3 -3
  138. package/dist/useCollapsePanel.d.ts +3 -3
  139. package/dist/useCropperCore.d.cts +6 -6
  140. package/dist/useCropperCore.d.ts +6 -6
  141. package/dist/useDraggableLayout.d.cts +13 -11
  142. package/dist/useDraggableLayout.d.ts +13 -11
  143. package/dist/useDynamicFormState.d.cts +2 -2
  144. package/dist/useDynamicFormState.d.ts +2 -2
  145. package/dist/useEdgeInteraction.d.cts +2 -2
  146. package/dist/useEdgeInteraction.d.ts +2 -2
  147. package/dist/useFullscreen.d.cts +6 -2
  148. package/dist/useFullscreen.d.ts +6 -2
  149. package/dist/useGlobalSearch.d.cts +9 -4
  150. package/dist/useGlobalSearch.d.ts +9 -4
  151. package/dist/useInfiniteScroll.d.cts +4 -1
  152. package/dist/useInfiniteScroll.d.ts +4 -1
  153. package/dist/useQRCode.d.cts +3 -3
  154. package/dist/useQRCode.d.ts +3 -3
  155. package/dist/useSearchState.d.cts +3 -3
  156. package/dist/useSearchState.d.ts +3 -3
  157. package/dist/useSignatureHistory.d.cts +5 -5
  158. package/dist/useSignatureHistory.d.ts +5 -5
  159. package/dist/useSplitResize.d.cts +8 -8
  160. package/dist/useSplitResize.d.ts +8 -8
  161. package/dist/useTableQuery.cjs +2 -2
  162. package/dist/useTableQuery.d.cts +20 -10
  163. package/dist/useTableQuery.d.ts +20 -10
  164. package/dist/useTableQuery.js +2 -2
  165. package/dist/useTimeSelection.d.cts +3 -3
  166. package/dist/useTimeSelection.d.ts +3 -3
  167. package/dist/useWorkflowValidation.d.cts +2 -2
  168. package/dist/useWorkflowValidation.d.ts +2 -2
  169. package/dist/verification.d.cts +5 -5
  170. package/dist/verification.d.ts +5 -5
  171. package/docs/component-review-20261019.md +55 -0
  172. package/docs/guides/runtime-performance.md +38 -0
  173. package/docs/guides/split-pane.en.md +4 -0
  174. package/docs/guides/split-pane.md +4 -0
  175. package/docs/guides/table-density.md +20 -0
  176. package/docs/guides/transfer.md +11 -0
  177. package/docs/runtime-review-20261019.md +41 -0
  178. package/package.json +4 -2
@@ -44,26 +44,26 @@ interface TimeExpose {
44
44
  //#endregion
45
45
  //#region src/components/C_Time/index.vue.d.ts
46
46
  declare const __VLS_export: vue.DefineComponent<TimeProps, TimeExpose, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
47
- "update:modelValue": (value: TimeModelValue) => any;
48
47
  change: (value: TimeModelValue) => any;
48
+ "update:modelValue": (value: TimeModelValue) => any;
49
49
  "change-range": (startTime: number | null, endTime: number | null) => any;
50
50
  "change-single": (time: number | null) => any;
51
51
  "change-start": (time: number | null) => any;
52
52
  "change-end": (time: number | null) => any;
53
53
  }, string, vue.PublicProps, Readonly<TimeProps> & Readonly<{
54
- "onUpdate:modelValue"?: ((value: TimeModelValue) => any) | undefined;
55
54
  onChange?: ((value: TimeModelValue) => any) | undefined;
55
+ "onUpdate:modelValue"?: ((value: TimeModelValue) => any) | undefined;
56
56
  "onChange-range"?: ((startTime: number | null, endTime: number | null) => any) | undefined;
57
57
  "onChange-single"?: ((time: number | null) => any) | undefined;
58
58
  "onChange-start"?: ((time: number | null) => any) | undefined;
59
59
  "onChange-end"?: ((time: number | null) => any) | undefined;
60
60
  }>, {
61
61
  placeholder: string;
62
- format: string;
63
62
  mode: TimeMode;
64
63
  attrs: Record<string, any>;
65
64
  startPlaceholder: string;
66
65
  endPlaceholder: string;
66
+ format: string;
67
67
  useHours: boolean;
68
68
  useMinutes: boolean;
69
69
  useSeconds: boolean;
@@ -44,26 +44,26 @@ interface TimeExpose {
44
44
  //#endregion
45
45
  //#region src/components/C_Time/index.vue.d.ts
46
46
  declare const __VLS_export: vue.DefineComponent<TimeProps, TimeExpose, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
47
- "update:modelValue": (value: TimeModelValue) => any;
48
47
  change: (value: TimeModelValue) => any;
48
+ "update:modelValue": (value: TimeModelValue) => any;
49
49
  "change-range": (startTime: number | null, endTime: number | null) => any;
50
50
  "change-single": (time: number | null) => any;
51
51
  "change-start": (time: number | null) => any;
52
52
  "change-end": (time: number | null) => any;
53
53
  }, string, vue.PublicProps, Readonly<TimeProps> & Readonly<{
54
- "onUpdate:modelValue"?: ((value: TimeModelValue) => any) | undefined;
55
54
  onChange?: ((value: TimeModelValue) => any) | undefined;
55
+ "onUpdate:modelValue"?: ((value: TimeModelValue) => any) | undefined;
56
56
  "onChange-range"?: ((startTime: number | null, endTime: number | null) => any) | undefined;
57
57
  "onChange-single"?: ((time: number | null) => any) | undefined;
58
58
  "onChange-start"?: ((time: number | null) => any) | undefined;
59
59
  "onChange-end"?: ((time: number | null) => any) | undefined;
60
60
  }>, {
61
61
  placeholder: string;
62
- format: string;
63
62
  mode: TimeMode;
64
63
  attrs: Record<string, any>;
65
64
  startPlaceholder: string;
66
65
  endPlaceholder: string;
66
+ format: string;
67
67
  useHours: boolean;
68
68
  useMinutes: boolean;
69
69
  useSeconds: boolean;
@@ -237,15 +237,15 @@ declare const __VLS_export: vue.DefineComponent<WorkflowProps, {
237
237
  conditionNodes: number;
238
238
  }>;
239
239
  }, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
240
- "update:modelValue": (value: WorkflowData) => any;
241
240
  change: (value: WorkflowData) => any;
241
+ "update:modelValue": (value: WorkflowData) => any;
242
242
  save: (data: WorkflowData) => any;
243
243
  "validate-error": (errors: ValidationError[]) => any;
244
244
  "node-click": (node: WorkflowNode) => any;
245
245
  "edge-click": (edge: WorkflowEdge) => any;
246
246
  }, string, vue.PublicProps, Readonly<WorkflowProps> & Readonly<{
247
- "onUpdate:modelValue"?: ((value: WorkflowData) => any) | undefined;
248
247
  onChange?: ((value: WorkflowData) => any) | undefined;
248
+ "onUpdate:modelValue"?: ((value: WorkflowData) => any) | undefined;
249
249
  onSave?: ((data: WorkflowData) => any) | undefined;
250
250
  "onValidate-error"?: ((errors: ValidationError[]) => any) | undefined;
251
251
  "onNode-click"?: ((node: WorkflowNode) => any) | undefined;
@@ -237,15 +237,15 @@ declare const __VLS_export: vue.DefineComponent<WorkflowProps, {
237
237
  conditionNodes: number;
238
238
  }>;
239
239
  }, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
240
- "update:modelValue": (value: WorkflowData) => any;
241
240
  change: (value: WorkflowData) => any;
241
+ "update:modelValue": (value: WorkflowData) => any;
242
242
  save: (data: WorkflowData) => any;
243
243
  "validate-error": (errors: ValidationError[]) => any;
244
244
  "node-click": (node: WorkflowNode) => any;
245
245
  "edge-click": (edge: WorkflowEdge) => any;
246
246
  }, string, vue.PublicProps, Readonly<WorkflowProps> & Readonly<{
247
- "onUpdate:modelValue"?: ((value: WorkflowData) => any) | undefined;
248
247
  onChange?: ((value: WorkflowData) => any) | undefined;
248
+ "onUpdate:modelValue"?: ((value: WorkflowData) => any) | undefined;
249
249
  onSave?: ((data: WorkflowData) => any) | undefined;
250
250
  "onValidate-error"?: ((errors: ValidationError[]) => any) | undefined;
251
251
  "onNode-click"?: ((node: WorkflowNode) => any) | undefined;
@@ -76,24 +76,24 @@ declare const __VLS_export: vue.DefineComponent<CaptchaProps, {
76
76
  reset: () => void;
77
77
  show: () => void;
78
78
  }, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {} & {
79
- success: (data: CaptchaSuccessPayload) => any;
80
79
  change: (valid: boolean) => any;
80
+ success: (data: CaptchaSuccessPayload) => any;
81
+ "load-error": (error: unknown) => any;
81
82
  reset: () => any;
82
83
  fail: (error: string) => any;
83
84
  "verify-error": (error: unknown) => any;
84
- "load-error": (error: unknown) => any;
85
85
  "visible-change": (visible: boolean) => any;
86
86
  }, string, vue.PublicProps, Readonly<CaptchaProps> & Readonly<{
87
- onSuccess?: ((data: CaptchaSuccessPayload) => any) | undefined;
88
87
  onChange?: ((valid: boolean) => any) | undefined;
88
+ onSuccess?: ((data: CaptchaSuccessPayload) => any) | undefined;
89
+ "onLoad-error"?: ((error: unknown) => any) | undefined;
89
90
  onReset?: (() => any) | undefined;
90
91
  onFail?: ((error: string) => any) | undefined;
91
92
  "onVerify-error"?: ((error: unknown) => any) | undefined;
92
- "onLoad-error"?: ((error: unknown) => any) | undefined;
93
93
  "onVisible-change"?: ((visible: boolean) => any) | undefined;
94
94
  }>, {
95
- disabled: boolean;
96
95
  theme: "light" | "dark";
96
+ disabled: boolean;
97
97
  provider: CaptchaProvider;
98
98
  images: string[];
99
99
  verificationTimeout: number;
@@ -76,24 +76,24 @@ declare const __VLS_export: vue.DefineComponent<CaptchaProps, {
76
76
  reset: () => void;
77
77
  show: () => void;
78
78
  }, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {} & {
79
- success: (data: CaptchaSuccessPayload) => any;
80
79
  change: (valid: boolean) => any;
80
+ success: (data: CaptchaSuccessPayload) => any;
81
+ "load-error": (error: unknown) => any;
81
82
  reset: () => any;
82
83
  fail: (error: string) => any;
83
84
  "verify-error": (error: unknown) => any;
84
- "load-error": (error: unknown) => any;
85
85
  "visible-change": (visible: boolean) => any;
86
86
  }, string, vue.PublicProps, Readonly<CaptchaProps> & Readonly<{
87
- onSuccess?: ((data: CaptchaSuccessPayload) => any) | undefined;
88
87
  onChange?: ((valid: boolean) => any) | undefined;
88
+ onSuccess?: ((data: CaptchaSuccessPayload) => any) | undefined;
89
+ "onLoad-error"?: ((error: unknown) => any) | undefined;
89
90
  onReset?: (() => any) | undefined;
90
91
  onFail?: ((error: string) => any) | undefined;
91
92
  "onVerify-error"?: ((error: unknown) => any) | undefined;
92
- "onLoad-error"?: ((error: unknown) => any) | undefined;
93
93
  "onVisible-change"?: ((visible: boolean) => any) | undefined;
94
94
  }>, {
95
- disabled: boolean;
96
95
  theme: "light" | "dark";
96
+ disabled: boolean;
97
97
  provider: CaptchaProvider;
98
98
  images: string[];
99
99
  verificationTimeout: number;
@@ -0,0 +1,55 @@
1
+ # 表格布局、性能与组件复查
2
+
3
+ 日期:2026-10-19。基线为 `v0.17.0`,本轮修改通过 Changeset 登记为后续补丁,不将源码合入描述为已发布新 npm 版本。
4
+
5
+ ## 展开列间距的原因与默认行为
6
+
7
+ 原样式给非末列统一加 `min-width: 80px !important`;普通列映射又为辅助列填入业务默认宽度,展开/选择增强器随后丢弃显式元数据。宽屏自动布局还会把空余空间分给所有定宽列,不能只改一个 CSS 数字。
8
+
9
+ 本轮将辅助列默认宽度收敛为选择 40、展开 40、序号 50。未声明宽度的普通非固定业务列保持自然弹性,并保留首选最小宽度;辅助列与弹性业务列共存时默认采用原生 fixed 布局。显式宽度、上限、固定位置、全局列宽和原生 table-layout 不被改写。所有业务列均显式定宽时保留原生余量分配语义。
10
+
11
+ 相同 1440px 独立浏览器场景中,0.17.0 的三个辅助列各约 142.56px;修改后为 40/40/50px。该场景含一列未指定宽度、最小宽度 220px 的名称列,同时测试普通与固定列布局。详细配置见[表格指南](./guides/table-density.md)。
12
+
13
+ ## 性能改进的可验证范围
14
+
15
+ | 位置 | 原问题 | 修改与验证 |
16
+ | -------------- | --------------------------------------------- | ----------------------------------------------------------------------------------- |
17
+ | 程序化跨页选择 | 每选择一个键都扫描本地数据 | 首次使用时建索引,重复查询复用;1 万行选择末尾 100 行,rowKey 调用 995,150 → 10,100 |
18
+ | 批量展开 | 每个新键线性找行,差集反复 includes | 惰性行键索引与 Set 差集;1 万键展开线性访问,不重复扫描 |
19
+ | 树行辅助遍历 | 深度递归可栈溢出 | 迭代 DFS,保留对象身份、顺序和循环/共享节点去重 |
20
+ | 表单修改检测 | 只判断是否修改仍比较所有字段 | 首个差异短路;嵌套 Map/Set 修改仍可触发外层计算 |
21
+ | 图和甘特实例 | 第三方大型对象被 Vue 深代理,同帧配置多次重建 | 原始实例浅引用,甘特主题/配置合并监听与重复初始化取消 |
22
+
23
+ 以上是算法调用量和生命周期验证,不表示整表 FPS 按同比例提升。2 万深、15 万宽的辅助遍历测试不代表 Naive 原生能渲染同等规模的 DOM;实际大表仍应使用分页、虚拟滚动、稳定且唯一的 rowKey。
24
+
25
+ ## 其他已修复问题
26
+
27
+ | 组件 | 修改 |
28
+ | ------------------------ | --------------------------------------------------------------------------------- |
29
+ | Login | 异步校验任务锁;等待后重新核对禁用、加载、表单快照、视图与卸载状态 |
30
+ | ImageCropper / Signature | 新读取、清空、替换与卸载使旧图片结果失效;裁剪导出在 scope 结束时结算并释放计时器 |
31
+ | WorkFlow | 清理旧定位延迟;卸载、替换画布、删除节点或重置后不打开旧配置 |
32
+ | TagsView | 批量关闭保留所有 affix 固定标签 |
33
+ | Chat | 历史前插保留阅读位置;同条数切换会话定位;末条消息更新仅在接近底部时跟随 |
34
+ | VideoPlayer | 常规 WebVTT 时间行正确解析;复用字幕请求,防切换乱序、关闭后重开和卸载后写入 |
35
+ | Barcode | 按真实 vendor 契约传入 options,非法内容触发 error 并支持恢复 |
36
+ | Draggable | 跨列表及克隆事件返回真实业务对象,避免把 DOM 或邻项当业务数据 |
37
+
38
+ ## 审查范围与后续空间
39
+
40
+ 后续进展:本节列出的列表窗口化、字幕索引、瀑布流图片批处理及 Code/QRCode 异步边界已在后续专项处理中完善,见[大列表与异步任务](./guides/runtime-performance.md)。下文保留本次表格复查时的记录,不能将两个阶段的测试数量混用。
41
+
42
+ 本轮逐项源码审读 51 个公开组件:表单/表格/树与分割、导航/标签/主题、消息/工作流、图表、媒体/编辑器、选择/拖拽、加载与其他工具组件。Map、OrgChart、FilePreview、Upload 在另一个活动工作区单独改进,本轮不覆盖或混入其未提交修改。公共 `_shared` 目录不计作业务组件。
43
+
44
+ 审读重点是高频计算、重复初始化、事件/observer/计时器释放、异步任务身份、公开事件和 vendor 真实接入。只有已修改路径及明确场景有新增针对性回归,不能将源码审读等同于所有组件、浏览器、第三方引擎都做了压测。
45
+
46
+ 仍有专项空间:WaterFall 图片布局批处理与窗口化、Chat/Transfer/GlobalSearch 等海量列表的窗口化、长字幕的时间索引、媒体运行时配置切换与大文档编辑性能。现有普通 DOM 列表并非无限数据容器;应按实际数据量和耗时/内存证据推进,不为了统一形式给所有组件加入自建虚拟滚动和更多开关。
47
+
48
+ 次要异步状态仍可进一步完善:Code 快速切换语言时 loading 尚无独立请求代次;QRCode 的旧 Logo 图像请求虽不会提交过期结果,底层网络加载本身没有主动取消。这些没有作为本轮已修复项。
49
+
50
+ ## 本轮实际校验
51
+
52
+ - 完整 `bun run verify` 通过:282 项单元、173 项真实组件挂载,以及 TypeScript、Vue/组件/消费者声明、lint、构建、ESM/CJS 与 Node16/NodeNext 打包消费者契约检查。
53
+ - 包与四个轻量入口的体积预算通过,未放宽预算;消费者契约复用本机安装的依赖版本,没有宣称重新从公开 registry 安装了尚未发布的补丁。
54
+ - 隔离浏览器以 1440/720/420px、明暗主题和三种密度组合运行 18 组场景、36 个表格实例,核对实际辅助列宽、表头/表体对齐、业务最小宽度、展开/收起、真实选择和页面错误。对比基线使用已发布 0.17.0 的实际产物。
55
+ - 本轮没有运行真实业务后端、没有给所有第三方引擎做性能压测,也没有以 Chromium 结果替代其他浏览器/平台验收。
@@ -0,0 +1,38 @@
1
+ # 大列表与异步任务
2
+
3
+ 组件保持按需导入和现有事件契约。以下优化默认生效;普通接入无需配置虚拟列表引擎、分页游标或滚动状态。
4
+
5
+ ## 自动减少列表 DOM
6
+
7
+ | 组件 | 生效条件 | 保留的语义 |
8
+ | ---------------- | ---------------------------------- | ------------------------------------------------------------ |
9
+ | `C_Transfer` | 左右面板分别按筛选后项数,100 项起 | 完整数据筛选、全选、禁用项、移动顺序、v-model |
10
+ | `C_Chat` | 消息 200 条起;联系人 100 条起 | 图片、文件、系统消息、重发、联系人事件;实际测量变高行 |
11
+ | `C_GlobalSearch` | 搜索结果列表 | 完整匹配结果、上下键跨视口定位、Enter 选择、输入法与历史记录 |
12
+
13
+ ```vue
14
+ <C_Transfer v-model="selectedKeys" :data="people" filterable />
15
+ <C_Chat :messages="messages" :contacts="contacts" @send="sendMessage" />
16
+ <C_GlobalSearch :options="searchOptions" />
17
+ ```
18
+
19
+ 窗口化复用 `vueuc` 的公开 `VVirtualList`,兼容本包声明的 Naive UI 2.35;不依赖 Naive 内部导入,也不提高 Naive peer 下限。只减少渲染的 DOM,数据仍完整保存在内存中,搜索仍检查完整索引。
20
+
21
+ 穿梭框的三档行高和自定义方式见[穿梭框指南](./transfer.md)。聊天会实测文本、图片和文件行高度,无需调用方预先计算高度。业务 ID 应唯一、稳定;聊天容器应有确定高度,例如外层 `height: 600px`。
22
+
23
+ 若打印、DOM 集成或自定义穿梭框行高需要完整节点,可给 `C_Transfer` 或 `C_Chat` 设置 `:virtual-scroll="false"`。不要把此开关作为加载更多数据的接口;聊天加载历史仍通过 `load-more` 事件及 `loading-history` 状态接入。
24
+
25
+ ## 聊天滚动与输入
26
+
27
+ 打开或切换会话定位最新消息。阅读历史时,新增消息不抢滚动位置;前插历史保留阅读锚点。正在底部时,流式文本、迟到图片与面板高度变化继续跟随。跨越自动窗口化门槛也保持当前阅读状态。
28
+
29
+ 公开 `scrollToBottom()` 可用于主动跳到最新消息。输入法 Enter 确认候选不会提前发送;普通 Enter 保持发送行为。
30
+
31
+ ## 图片、字幕和异步状态
32
+
33
+ - 瀑布流将同帧图片测量合并为一次布局,参数变化和公开 `relayout()` 仍立即计算。替换图片来源后忽略旧测量,卸载时取消待执行帧。导出的 `useWaterFallLayout` 原有四参数用法保持同步行为。
34
+ - 字幕载入时编译时间索引;播放与前后跳转查询使用二分查找,保留重叠字幕按原文件顺序首匹配的语义。
35
+ - 代码语言加载只由当前请求更新 loading 和高亮。语言注册后主动更新高亮器引用,同一种语言异步加载完成也会重新着色。复制事件返回点击当时的文本。
36
+ - 二维码渲染及每次导出分别保存配置快照。新渲染取消旧 Logo 加载,导出相互独立;卸载取消所有任务并释放 Image 事件。组件销毁期间尚未完成的导出会以 `AbortError` 拒绝,调用方按普通异步错误处理即可。
37
+
38
+ 这些改进不代表列表、瀑布流和编辑器可以无限增加数据。大规模业务仍应按实际场景分段加载、回收历史,并测量内存、交互延迟与目标浏览器表现。
@@ -82,6 +82,10 @@ Existing uncontrolled usage remains supported. Moving the gutter outside the per
82
82
 
83
83
  ## Interaction
84
84
 
85
+ A fine divider line carries a centered capsule grip (80px long, 16px thick by default). Nearby collapse buttons appear on hover or keyboard focus and stay visible while collapsed. Borders, a restrained shadow and local accent feedback use the existing `--c-primary`, `--c-bg-card`, `--c-border` and `--c-text-3` theme tokens in both orientations.
86
+
87
+ The capsule itself accepts dragging without increasing the layout space reserved by `gutterSize`. Touch input gets a 24px grip thickness and permanently visible 28px buttons. Collapsed controls dock inside the container to avoid clipping. Inline SVG arrows require no remote icon request, and reduced-motion preferences disable transitions.
88
+
85
89
  The [W3C APG Window Splitter pattern](https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/) informs keyboard behavior and separator semantics. Use Left/Right for left/right layouts and Up/Down for top/bottom layouts. Home/End move to the current boundaries. Enter collapses the first pane or restores an already collapsed pane. Double-click toggles the first pane.
86
90
 
87
91
  Pointer Events support mouse, pen and touch. Pointer cancellation, window blur, document hiding, disablement, direction changes and unmounting all dispose listeners and restore the previous body cursor / text selection styles. Nested splitters do not overwrite `document.onmousemove`.
@@ -96,6 +96,10 @@
96
96
 
97
97
  ## 交互与无障碍
98
98
 
99
+ 手柄采用细轨道与居中胶囊握柄,默认长 80px、厚 16px,保留三点拖动提示。悬停和键盘聚焦时,在握柄两侧显示折叠入口,并以局部描边和轻阴影提示当前状态;折叠后入口持续显示。横向、纵向使用相同视觉规则,主题颜色复用 `--c-primary / --c-bg-card / --c-border / --c-text-3`。
100
+
101
+ 胶囊是独立的实际拖动区域,其视觉厚度不会改变 `gutterSize` 占用的布局空间。触屏下握柄厚度增至 24px、折叠按钮增至 28px,并保持按钮常驻;折叠到边缘时控件向容器内部停靠,避免被裁切。箭头使用本地 SVG,不请求远程图标。
102
+
99
103
  键盘交互与 separator 语义参照 [W3C APG Window Splitter](https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/)。可用 `aria-label="订单主表"` 设置面板对应的可访问名称。
100
104
 
101
105
  - 拖动支持鼠标、触控笔和触屏 Pointer Events,不接管宿主的 `document.onmousemove`。
@@ -65,3 +65,23 @@ const config = {
65
65
  分页、树表、虚拟滚动、选择、导出继续使用各自的分组配置。它们是可组合能力,不设隐含开启多种行为的“万能模式”。
66
66
 
67
67
  多表分屏请参阅[分割面板](./split-pane.md);表单优先级与布局示例请参阅[表单密度](./form-density.md)。
68
+
69
+ ## 展开、序号和弹性业务列
70
+
71
+ 默认辅助列宽度:选择列 `40px`、展开列 `40px`、序号列 `50px`。普通未固定的业务列不再被统一填上 `width: 180`;未指定宽度时,它按首选最小宽度吸收容器余量。有辅助列和自然弹性业务列时,默认使用原生 `fixed` 表格布局,避免空余空间把展开与序号撑大:
72
+
73
+ ```ts
74
+ const columns: TableColumn<Order>[] = [
75
+ { type: 'selection' },
76
+ { type: 'expand' },
77
+ { type: 'index' },
78
+ { key: 'name', title: '订单名称', minWidth: 220 }, // 自然弹性列
79
+ { key: 'amount', title: '金额', width: 140 },
80
+ ]
81
+ ```
82
+
83
+ 不需要给每张表写辅助列 CSS。显式列 `width / minWidth / maxWidth / fixed / className / cellProps` 保持转发;`config.display.columnWidth`(包括全局配置中的显式 `180`)仍表示统一列宽。固定业务列继续使用可计算的数值默认宽度;原生 `table-layout` 属性可覆盖自动选择的布局。
84
+
85
+ 若所有业务列都显式指定宽度,且总宽小于容器,保留原生表格的剩余空间分配规则;这时声明的 `width` 不保证等于最后测量的像素。通常让名称或描述列保持弹性,比给所有列设宽更合适。虚拟横向滚动仍需按 Naive UI 的契约提供具体列宽。
86
+
87
+ 独立的列 `renderExpand` 直接转交原生表格;配置 `config.expand.onLoadData / renderContent` 后由组件的加载、失败重试和内容渲染器接管展开区。不要同时配置两套展开内容并依赖原生渲染器优先。自动横向滚动宽度按最终可见列计算,包含辅助列、动态选择列和操作列,不再额外追加固定留白。
@@ -0,0 +1,11 @@
1
+ # 穿梭框与大列表
2
+
3
+ ```vue
4
+ <C_Transfer v-model="selectedKeys" :data="people" filterable />
5
+ ```
6
+
7
+ 左右面板分别按搜索后的项数决定渲染方式:少于 100 项使用普通列表,100 项起复用 Naive UI 同样使用的官方 `vueuc/VVirtualList`,只挂载当前视口及相邻行。全选、禁用判断和移动顺序仍以完整列表为准;滚动到视口之外的选中项不会丢失。右侧保持 `modelValue` 的顺序,新增项按左侧数据顺序追加。
8
+
9
+ `size="small | medium | large"` 对应 28 / 34 / 40px 固定行高。继续通过既有 `--tf-height` 覆盖列表高度,例如 `style="--tf-height: 240px"`;无需为大列表额外设置高度或分页。
10
+
11
+ 若项目自行改变行高、需要打印全部项,或依赖完整列表 DOM,可显式设置 `:virtual-scroll="false"` 保留普通渲染。默认开启自动判断,常规接入无需配置。搜索仍检查全部数据;虚拟列表减少 DOM 与组件挂载量,不把筛选或数据存储变成无限容量服务。
@@ -0,0 +1,41 @@
1
+ # 大列表、渲染与异步任务专项复查
2
+
3
+ 日期:2026-10-19。本轮接续[表格与组件复查](./component-review-20261019.md),并合并远端 `fdffe29` 中已提交的地图、组织图、预览、上传、甘特及瀑布流修复。功能变更通过 Changeset 登记,源码合入不等于发布新的 npm 版本。
4
+
5
+ ## 修改及可验证收益
6
+
7
+ | 路径 | 实际改进 | 验证方式 |
8
+ | ------------- | ----------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
9
+ | Transfer | 每侧筛选结果 100 项起窗口化;保留完整选择和移动语义;普通接入零新增必填项 | 3000 项的真实列表仅挂载视口附近的行;三档行高 28/34/40px,筛选末项、禁用保护、移动和完整 DOM 逃生回归 |
10
+ | GlobalSearch | 菜单派生文本缓存;完整结果窗口化;跨视口键盘定位 | 1 万菜单连续 4 次搜索,label/key 各读取 1 万次;5000 匹配结果保留,键盘定位第 1201 项并返回正确 key |
11
+ | Chat | 消息 200 条、联系人 100 条起自动窗口化;变高行交给公开引擎实测 | 1000 消息、500 联系人实际 DOM 有界;文件/图片/重发事件,历史前插、流式、迟到图片、会话切换、门槛及尺寸变化回归 |
12
+ | WaterFall | 图片与标题/插槽高度测量合并为单帧布局;RO 条目与元素登记用 Map 查询 | 1000 项中 100 张图片与 100 次标题测量只发布一次布局;显式 relayout/配置变化仍立即计算;三种宽度长标题无重叠 |
13
+ | Subtitle | 编译保留源顺序优先级的区间索引,二分查询 | 重叠、乱序、相同边界及反向跳转对照线性参考;10 万字幕每次查询最多 19 次区间读取 |
14
+ | Code / QRCode | 当前任务拥有 loading/输出;复制及导出保留输入快照;卸载取消迟到结果及 Logo 图片事件 | 真正 NCode 同语言异步重高亮、快速切换、复制快照;二维码并发导出、取消、绘图异常和卸载回归 |
15
+
16
+ DOM 数量和算法访问次数说明对应瓶颈的变化,不代表整页 FPS 或所有数据规模的同倍数改善。虚拟列表仍保留全部内存数据,实际业务应按需分段加载。
17
+
18
+ ## 使用侧与兼容性
19
+
20
+ 自动窗口化复用 `vueuc` 的公开 `VVirtualList`,通过直接依赖声明,未使用 Naive 内部导入,也未将 Naive peer 从 2.35 提高到 2.36。`C_Transfer` 与 `C_Chat` 可用 `virtualScroll=false` 保留完整 DOM。聊天 ID 应唯一稳定,容器应有确定高度。
21
+
22
+ 穿梭框保留 `--tf-height`。聊天变高行不要求业务填写高度;输入法 Enter 确认候选不会发送。公开 `useWaterFallLayout` 四参数调用仍同步,实际组件才显式开启批处理。二维码组件销毁时未完成的导出以 `AbortError` 拒绝;并行导出互不取消。
23
+
24
+ 具体接入与边界见[大列表与异步任务](./guides/runtime-performance.md)及[穿梭框指南](./guides/transfer.md)。
25
+
26
+ ## 代码质量与验证边界
27
+
28
+ 索引、任务和滚动逻辑拆分到各自小模块,模板样式跟随提取的子组件收集;保留公开事件 payload,没有放宽质量或体积预算。合并瀑布流时保留远端的标题高度修复,并将逐条查找和逐元素扫描改为索引,ref 清空、行删除、卸载都会释放观察。
29
+
30
+ 验证采用本机 Bun 1.4.2、Vue 3.5.42、Naive 2.45.3;额外用真实 Naive 2.35.0 包 alias 验证本轮四个相关组件,不将 mock 当兼容证明。
31
+
32
+ - 合并后完整 `bun run verify`:306 项 Bun 单元、207 项组件挂载,以及 TypeScript/Vue/消费者类型、构建、55 个 ESM/CJS 组件入口、Node16/NodeNext 打包消费者契约均通过。
33
+ - Naive 2.35.0:36 项相关挂载测试和四组件类型检查通过。
34
+ - `bun install --frozen-lockfile --offline --ignore-scripts` 通过;包与轻量入口体积预算保持原值。消费者依赖复用本机已安装版本,未声称从公开 registry 全新安装尚未发布的版本。
35
+ - Chromium 合成场景核对 3000 项穿梭框、5000 项搜索、1000 条聊天及 500 联系人;另验证 199/200 条切换、面板变矮、普通历史前插迟到图片和 IME。明暗主题及窄屏截图检查,未发现运行异常。
36
+ - 使用构建后的命名导出及各组件独立 CSS 入口重复 27 项浏览器检查全部通过,确认抽取的消息、联系人和穿梭框行样式包含在按需产物中。
37
+ - 瀑布流浏览器核对 100 图、40 个含长标题条目,在 1000/700/420px 容器下无重叠;移除条目立即解除观察,卸载无残留观察目标或 RO 循环错误。
38
+
39
+ 全库 lint 无错误;未修改路径及合入的既有路径仍存在复杂度/解构建议警告,本轮修改的性能模块没有新增警告。以上不替代其他浏览器、真实业务后端或全部第三方引擎的长期压测。
40
+
41
+ 瀑布流此次解决测量和重排,不包含其窗口化协议;媒体运行时配置切换、大文档编辑和特定业务巨量数据仍应按实际 profile 做专项。不能据本轮结果宣称组件库已无优化空间。
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.17.0",
6
+ "version": "0.17.1",
7
7
  "description": "基于 Naive UI 的 Vue 3 组件库",
8
8
  "packageManager": "bun@1.3.14",
9
9
  "engines": {
@@ -132,7 +132,6 @@
132
132
  }
133
133
  },
134
134
  "dependencies": {
135
- "@robot-admin/form-validate": "3.4.2",
136
135
  "@antv/x6": "^2.19.2",
137
136
  "@chenfengyuan/vue-barcode": "^2.0.2",
138
137
  "@fullcalendar/core": "^6.1.21",
@@ -141,8 +140,10 @@
141
140
  "@fullcalendar/list": "^6.1.21",
142
141
  "@fullcalendar/vue3": "^6.1.21",
143
142
  "@iconify/vue": "^5.0.1",
143
+ "@robot-admin/form-validate": "3.4.2",
144
144
  "@types/leaflet": "^1.9.22",
145
145
  "@visactor/vtable": "^1.26.7",
146
+ "@visactor/vtable-editors": "^1.26.7",
146
147
  "@visactor/vtable-gantt": "^1.26.7",
147
148
  "@vue-flow/core": "^1.48.2",
148
149
  "@wangeditor-next/editor": "6.2.0",
@@ -161,6 +162,7 @@
161
162
  "vue-cropper": "^1.1.4",
162
163
  "vue-draggable-plus": "^0.6.1",
163
164
  "vue3-puzzle-vcode": "^1.1.7",
165
+ "vueuc": "^0.4.66",
164
166
  "xgplayer": "3.0.26",
165
167
  "xgplayer-hls": "3.0.26",
166
168
  "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"