@aspire-ui/element-component-pro 1.0.24 → 1.0.26

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.
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .ecp-pro-table[data-v-3d780f58]{padding:16px;background:#fff;width:100%;box-sizing:border-box}.ecp-pro-table[data-v-3d780f58] .el-table{width:100%!important}.ecp-pro-table__header[data-v-3d780f58]{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.ecp-pro-table__title-wrapper[data-v-3d780f58]{display:flex;align-items:center;gap:4px}.ecp-pro-table__title[data-v-3d780f58]{font-size:16px;font-weight:600}.ecp-pro-table__help[data-v-3d780f58]{color:#909399;cursor:help}.ecp-pro-table__toolbar[data-v-3d780f58]{display:flex;align-items:center;gap:8px}.ecp-pro-table__body[data-v-3d780f58]{width:100%}.ecp-pro-table__pagination[data-v-3d780f58]{margin-top:16px;display:flex;justify-content:flex-end}.ecp-pro-table__col-help[data-v-3d780f58]{margin-left:4px;color:#909399;cursor:help}.ecp-table-action[data-v-45a58e7c],.ecp-table-action__item[data-v-45a58e7c]{display:inline-flex;align-items:center;gap:4px}.ecp-table-action__icon[data-v-45a58e7c]{margin-right:4px}.ecp-table-action__more[data-v-45a58e7c]{display:inline-flex;align-items:center}.ecp-table-action__dropdown-item[data-v-45a58e7c]{display:inline-flex;align-items:center;gap:4px}.ecp-tree-select[data-v-f30bba11]{position:relative;width:100%}.ecp-tree-select__filter-inner[data-v-f30bba11]{margin-bottom:8px}.ecp-tree-select__dropdown[data-v-f30bba11]{position:absolute;top:100%;left:0;right:0;max-height:280px;overflow:auto;background:#fff;border:1px solid #dcdfe6;border-radius:4px;margin-top:4px;z-index:1000;padding:8px}.ecp-tree-select__loading[data-v-f30bba11]{padding:24px;text-align:center;color:#909399;font-size:14px}.ecp-pro-form-item__colon[data-v-48d7960b]{margin-right:2px}.ecp-pro-form-item__help-icon[data-v-48d7960b]{margin-left:4px;color:#909399;cursor:help;font-size:14px}.ecp-pro-form-item__help-icon[data-v-48d7960b]:hover{color:#409eff}.ecp-pro-form-item__help-item[data-v-48d7960b]{margin-bottom:4px}.ecp-pro-form-item__help-item[data-v-48d7960b]:last-child{margin-bottom:0}.ecp-form-actions[data-v-489c88d2]{text-align:right}.ecp-form-actions__advance[data-v-489c88d2]{margin-right:8px}.el-icon-d-arrow-left.up[data-v-489c88d2]{transform:rotate(90deg)}.el-icon-d-arrow-left.down[data-v-489c88d2]{transform:rotate(-90deg)}.ecp-pro-form[data-v-cf7b3b35]{padding:16px;position:relative}.ecp-pro-form__advance[data-v-cf7b3b35]{margin-bottom:16px}.ecp-pro-form .ecp-pro-form_col[data-v-cf7b3b35]{position:relative;float:right}.el-icon-d-arrow-left.up[data-v-cf7b3b35]{transform:rotate(90deg)}.el-icon-d-arrow-left.down[data-v-cf7b3b35]{transform:rotate(-90deg)}.ecp-form-actions__advance[data-v-cf7b3b35]{position:absolute;bottom:0;left:50%;transform:translate(-50%,-50%)}.ecp-pro-descriptions[data-v-656036f6]{width:100%;box-sizing:border-box}.ecp-pro-descriptions__header[data-v-656036f6]{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;gap:12px}.ecp-pro-descriptions__title-wrap[data-v-656036f6]{display:flex;align-items:center;gap:6px}.ecp-pro-descriptions__title[data-v-656036f6]{font-size:16px;font-weight:600;color:#303133}.ecp-pro-descriptions__help[data-v-656036f6],.ecp-pro-descriptions__toggle[data-v-656036f6]{color:#909399}.ecp-pro-descriptions__toggle .el-icon-arrow-down[data-v-656036f6]{margin-left:4px;transition:transform .2s ease}.ecp-pro-descriptions__toggle .el-icon-arrow-down.is-expanded[data-v-656036f6]{transform:rotate(180deg)}.ecp-pro-descriptions__body[data-v-656036f6]{display:grid;border-top:1px solid #ebeef5;border-left:1px solid #ebeef5;overflow:hidden}.ecp-pro-descriptions__body.is-collapsed[data-v-656036f6]{overflow:hidden}.ecp-pro-descriptions__body[data-v-656036f6]:not(.is-bordered){border-top:0;border-left:0;gap:12px 16px}.ecp-pro-descriptions__item[data-v-656036f6]{display:flex;min-width:0;border-right:1px solid #ebeef5;border-bottom:1px solid #ebeef5}.ecp-pro-descriptions__body:not(.is-bordered) .ecp-pro-descriptions__item[data-v-656036f6]{border-right:0;border-bottom:0}.ecp-pro-descriptions__label[data-v-656036f6],.ecp-pro-descriptions__content[data-v-656036f6]{min-width:0;box-sizing:border-box;word-break:break-word}.ecp-pro-descriptions__label[data-v-656036f6]{flex:0 0 120px;padding:12px 16px;color:#606266;background:#fafafa}.ecp-pro-descriptions__content[data-v-656036f6]{flex:1;padding:12px 16px;color:#303133;background:#fff}.ecp-pro-descriptions__body:not(.is-bordered) .ecp-pro-descriptions__label[data-v-656036f6]{flex-basis:auto;padding:0;margin-right:8px;background:transparent;font-weight:500}.ecp-pro-descriptions__body:not(.is-bordered) .ecp-pro-descriptions__content[data-v-656036f6]{padding:0;background:transparent}.ecp-pro-descriptions__body.is-small .ecp-pro-descriptions__label[data-v-656036f6],.ecp-pro-descriptions__body.is-small .ecp-pro-descriptions__content[data-v-656036f6]{padding-top:8px;padding-bottom:8px;font-size:13px}@media (max-width: 767px){.ecp-pro-descriptions__item[data-v-656036f6]{flex-direction:column}.ecp-pro-descriptions__label[data-v-656036f6]{flex-basis:auto}}.ecp-collapse-container[data-v-087dba3a]{background:#fff;border-radius:14px;border:1px solid #e8eef8;box-shadow:0 10px 24px #0f2d5e0f;overflow:hidden}.ecp-collapse-container.is-ghost[data-v-087dba3a]{border-color:transparent;box-shadow:none;background:transparent}.ecp-collapse-container__header[data-v-087dba3a]{min-height:56px;padding:0 20px;display:flex;align-items:center;justify-content:space-between;gap:16px;border-bottom:1px solid #eef3fb}.ecp-collapse-container.is-ghost .ecp-collapse-container__header[data-v-087dba3a]{padding-left:0;padding-right:0}.ecp-collapse-container__header-main[data-v-087dba3a]{min-width:0;flex:1;display:flex;align-items:center}.ecp-collapse-container__title-wrap[data-v-087dba3a]{min-width:0;display:inline-flex;align-items:center;gap:8px}.ecp-collapse-container__title[data-v-087dba3a]{color:#1f2d3d;font-size:16px;font-weight:600;line-height:1.4}.ecp-collapse-container__help[data-v-087dba3a]{color:#91a3b7;font-size:14px}.ecp-collapse-container__header-extra[data-v-087dba3a]{display:inline-flex;align-items:center;justify-content:flex-end;gap:12px;flex-shrink:0}.ecp-collapse-container__toggle[data-v-087dba3a]{padding:0;color:#2f6fd3}.ecp-collapse-container__toggle i[data-v-087dba3a]{margin-left:6px;transition:transform .2s ease}.ecp-collapse-container__toggle i.is-expanded[data-v-087dba3a]{transform:rotate(180deg)}.ecp-collapse-container__body[data-v-087dba3a]{padding:20px;box-sizing:border-box}.ecp-collapse-container.is-ghost .ecp-collapse-container__body[data-v-087dba3a]{padding-left:0;padding-right:0}.ecp-collapse-container.is-header-clickable .ecp-collapse-container__header-main[data-v-087dba3a]{cursor:pointer}@media (max-width: 768px){.ecp-collapse-container__header[data-v-087dba3a]{padding:14px 16px;align-items:flex-start;flex-direction:column}.ecp-collapse-container__header-extra[data-v-087dba3a]{width:100%;justify-content:space-between}.ecp-collapse-container__body[data-v-087dba3a]{padding:16px}}.ecp-pro-table-form__form[data-v-44aa7592] .el-form-item{margin-bottom:0}.ecp-pro-table-form__cell-item[data-v-44aa7592]{width:100%}.ecp-pro-table-form__cell-item[data-v-44aa7592] .el-form-item__content{margin-left:0!important;line-height:normal}.ecp-pro-table-form__fixed-label[data-v-44aa7592]{color:#303133;font-size:14px}.ecp-pro-table-form__req[data-v-44aa7592]{color:#f56c6c;margin-right:2px}.ecp-pro-table-form__th-text[data-v-44aa7592]{font-weight:500;color:#606266}.ecp-pro-table-form__action-title[data-v-44aa7592]{margin-right:8px;font-size:13px;color:#606266}.ecp-pro-table-form__add-btn[data-v-44aa7592]{padding:0;font-size:14px}.ecp-pro-table-form__del-btn[data-v-44aa7592]{padding:0;color:#909399}.ecp-pro-table-form__del-btn[data-v-44aa7592]:not(:disabled){color:#409eff}.ecp-pro-table-form .ecp-pro-table-form__header-cell{background:#f5f7fa!important}
1
+ .ecp-pro-table[data-v-d48fd076]{padding:16px;background:#fff;width:100%;box-sizing:border-box}.ecp-pro-table[data-v-d48fd076] .el-table{width:100%!important}.ecp-pro-table__header[data-v-d48fd076]{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.ecp-pro-table__title-wrapper[data-v-d48fd076]{display:flex;align-items:center;gap:4px}.ecp-pro-table__title[data-v-d48fd076]{font-size:16px;font-weight:600}.ecp-pro-table__help[data-v-d48fd076]{color:#909399;cursor:help}.ecp-pro-table__toolbar[data-v-d48fd076]{display:flex;align-items:center;gap:8px}.ecp-pro-table__body[data-v-d48fd076]{width:100%}.ecp-pro-table__pagination[data-v-d48fd076]{margin-top:16px;display:flex;justify-content:flex-end}.ecp-pro-table__col-help[data-v-d48fd076]{margin-left:4px;color:#909399;cursor:help}.ecp-table-action[data-v-45a58e7c],.ecp-table-action__item[data-v-45a58e7c]{display:inline-flex;align-items:center;gap:4px}.ecp-table-action__icon[data-v-45a58e7c]{margin-right:4px}.ecp-table-action__more[data-v-45a58e7c]{display:inline-flex;align-items:center}.ecp-table-action__dropdown-item[data-v-45a58e7c]{display:inline-flex;align-items:center;gap:4px}.ecp-tree-select[data-v-f30bba11]{position:relative;width:100%}.ecp-tree-select__filter-inner[data-v-f30bba11]{margin-bottom:8px}.ecp-tree-select__dropdown[data-v-f30bba11]{position:absolute;top:100%;left:0;right:0;max-height:280px;overflow:auto;background:#fff;border:1px solid #dcdfe6;border-radius:4px;margin-top:4px;z-index:1000;padding:8px}.ecp-tree-select__loading[data-v-f30bba11]{padding:24px;text-align:center;color:#909399;font-size:14px}.ecp-pro-form-item__colon[data-v-48d7960b]{margin-right:2px}.ecp-pro-form-item__help-icon[data-v-48d7960b]{margin-left:4px;color:#909399;cursor:help;font-size:14px}.ecp-pro-form-item__help-icon[data-v-48d7960b]:hover{color:#409eff}.ecp-pro-form-item__help-item[data-v-48d7960b]{margin-bottom:4px}.ecp-pro-form-item__help-item[data-v-48d7960b]:last-child{margin-bottom:0}.ecp-form-actions[data-v-489c88d2]{text-align:right}.ecp-form-actions__advance[data-v-489c88d2]{margin-right:8px}.el-icon-d-arrow-left.up[data-v-489c88d2]{transform:rotate(90deg)}.el-icon-d-arrow-left.down[data-v-489c88d2]{transform:rotate(-90deg)}.ecp-pro-form[data-v-cf7b3b35]{padding:16px;position:relative}.ecp-pro-form__advance[data-v-cf7b3b35]{margin-bottom:16px}.ecp-pro-form .ecp-pro-form_col[data-v-cf7b3b35]{position:relative;float:right}.el-icon-d-arrow-left.up[data-v-cf7b3b35]{transform:rotate(90deg)}.el-icon-d-arrow-left.down[data-v-cf7b3b35]{transform:rotate(-90deg)}.ecp-form-actions__advance[data-v-cf7b3b35]{position:absolute;bottom:0;left:50%;transform:translate(-50%,-50%)}.ecp-pro-descriptions[data-v-656036f6]{width:100%;box-sizing:border-box}.ecp-pro-descriptions__header[data-v-656036f6]{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;gap:12px}.ecp-pro-descriptions__title-wrap[data-v-656036f6]{display:flex;align-items:center;gap:6px}.ecp-pro-descriptions__title[data-v-656036f6]{font-size:16px;font-weight:600;color:#303133}.ecp-pro-descriptions__help[data-v-656036f6],.ecp-pro-descriptions__toggle[data-v-656036f6]{color:#909399}.ecp-pro-descriptions__toggle .el-icon-arrow-down[data-v-656036f6]{margin-left:4px;transition:transform .2s ease}.ecp-pro-descriptions__toggle .el-icon-arrow-down.is-expanded[data-v-656036f6]{transform:rotate(180deg)}.ecp-pro-descriptions__body[data-v-656036f6]{display:grid;border-top:1px solid #ebeef5;border-left:1px solid #ebeef5;overflow:hidden}.ecp-pro-descriptions__body.is-collapsed[data-v-656036f6]{overflow:hidden}.ecp-pro-descriptions__body[data-v-656036f6]:not(.is-bordered){border-top:0;border-left:0;gap:12px 16px}.ecp-pro-descriptions__item[data-v-656036f6]{display:flex;min-width:0;border-right:1px solid #ebeef5;border-bottom:1px solid #ebeef5}.ecp-pro-descriptions__body:not(.is-bordered) .ecp-pro-descriptions__item[data-v-656036f6]{border-right:0;border-bottom:0}.ecp-pro-descriptions__label[data-v-656036f6],.ecp-pro-descriptions__content[data-v-656036f6]{min-width:0;box-sizing:border-box;word-break:break-word}.ecp-pro-descriptions__label[data-v-656036f6]{flex:0 0 120px;padding:12px 16px;color:#606266;background:#fafafa}.ecp-pro-descriptions__content[data-v-656036f6]{flex:1;padding:12px 16px;color:#303133;background:#fff}.ecp-pro-descriptions__body:not(.is-bordered) .ecp-pro-descriptions__label[data-v-656036f6]{flex-basis:auto;padding:0;margin-right:8px;background:transparent;font-weight:500}.ecp-pro-descriptions__body:not(.is-bordered) .ecp-pro-descriptions__content[data-v-656036f6]{padding:0;background:transparent}.ecp-pro-descriptions__body.is-small .ecp-pro-descriptions__label[data-v-656036f6],.ecp-pro-descriptions__body.is-small .ecp-pro-descriptions__content[data-v-656036f6]{padding-top:8px;padding-bottom:8px;font-size:13px}@media (max-width: 767px){.ecp-pro-descriptions__item[data-v-656036f6]{flex-direction:column}.ecp-pro-descriptions__label[data-v-656036f6]{flex-basis:auto}}.ecp-collapse-container[data-v-087dba3a]{background:#fff;border-radius:14px;border:1px solid #e8eef8;box-shadow:0 10px 24px #0f2d5e0f;overflow:hidden}.ecp-collapse-container.is-ghost[data-v-087dba3a]{border-color:transparent;box-shadow:none;background:transparent}.ecp-collapse-container__header[data-v-087dba3a]{min-height:56px;padding:0 20px;display:flex;align-items:center;justify-content:space-between;gap:16px;border-bottom:1px solid #eef3fb}.ecp-collapse-container.is-ghost .ecp-collapse-container__header[data-v-087dba3a]{padding-left:0;padding-right:0}.ecp-collapse-container__header-main[data-v-087dba3a]{min-width:0;flex:1;display:flex;align-items:center}.ecp-collapse-container__title-wrap[data-v-087dba3a]{min-width:0;display:inline-flex;align-items:center;gap:8px}.ecp-collapse-container__title[data-v-087dba3a]{color:#1f2d3d;font-size:16px;font-weight:600;line-height:1.4}.ecp-collapse-container__help[data-v-087dba3a]{color:#91a3b7;font-size:14px}.ecp-collapse-container__header-extra[data-v-087dba3a]{display:inline-flex;align-items:center;justify-content:flex-end;gap:12px;flex-shrink:0}.ecp-collapse-container__toggle[data-v-087dba3a]{padding:0;color:#2f6fd3}.ecp-collapse-container__toggle i[data-v-087dba3a]{margin-left:6px;transition:transform .2s ease}.ecp-collapse-container__toggle i.is-expanded[data-v-087dba3a]{transform:rotate(180deg)}.ecp-collapse-container__body[data-v-087dba3a]{padding:20px;box-sizing:border-box}.ecp-collapse-container.is-ghost .ecp-collapse-container__body[data-v-087dba3a]{padding-left:0;padding-right:0}.ecp-collapse-container.is-header-clickable .ecp-collapse-container__header-main[data-v-087dba3a]{cursor:pointer}@media (max-width: 768px){.ecp-collapse-container__header[data-v-087dba3a]{padding:14px 16px;align-items:flex-start;flex-direction:column}.ecp-collapse-container__header-extra[data-v-087dba3a]{width:100%;justify-content:space-between}.ecp-collapse-container__body[data-v-087dba3a]{padding:16px}}.ecp-pro-table-form__form[data-v-3dfcfb4e] .el-form-item{margin-bottom:0}.ecp-pro-table-form__cell-item[data-v-3dfcfb4e]{width:100%}.ecp-pro-table-form__cell-item[data-v-3dfcfb4e] .el-form-item__content{margin-left:0!important;line-height:normal}.ecp-pro-table-form__req[data-v-3dfcfb4e]{color:#f56c6c;margin-right:2px}.ecp-pro-table-form__th-text[data-v-3dfcfb4e]{font-weight:500;color:#606266}.ecp-pro-table-form .ecp-pro-table-form__header-cell{background:#f5f7fa!important}.ecp-pro-table-form__cell-item .el-form-item__error{position:relative}
@@ -260,3 +260,225 @@ export interface DescriptionActionType {
260
260
  setData: (data: Record<string, unknown>) => Promise<void>;
261
261
  getData: () => Record<string, unknown>;
262
262
  }
263
+ /** el-form 实例 */
264
+ export interface FormInstance {
265
+ validate?(cb?: (valid: boolean) => void): Promise<unknown> | void;
266
+ clearValidate?(props?: string | string[]): void;
267
+ resetFields?(): void;
268
+ scrollToField?(name: string): void;
269
+ }
270
+ /** 指标列单元格渲染方式 */
271
+ export type ProTableFormBuiltInComponent = 'input' | 'input-number' | 'formatted-number' | 'select' | 'api-select' | 'tree-select' | 'date-picker' | 'date-range' | 'switch' | 'cascader' | 'checkbox' | 'radio' | 'slot';
272
+ /** 自定义渲染函数,返回文本或 VNode;参数为 { row, value, column } */
273
+ export type ProTableFormColumnRender = (params: {
274
+ row: Record<string, unknown>;
275
+ value: unknown;
276
+ column: ProTableFormColumn | ProTableFormColumnChild;
277
+ }) => string | VNode;
278
+ /** 指标列(或含友商名称等任意 key) */
279
+ export interface ProTableFormColumn {
280
+ /** 对应 model 中对象字段名 */
281
+ key: string;
282
+ title: string;
283
+ required?: boolean;
284
+ /** 单元格渲染方式:input / formatted-number / slot */
285
+ component?: ProTableFormBuiltInComponent;
286
+ /** component 为 slot 时必填,对应插槽名为 `cell-{slotName}` */
287
+ slotName?: string;
288
+ /**
289
+ * 自定义渲染,返回 string(文本)或 VNode(组件)。
290
+ * 若返回 string 且不为纯数字,单元格自动包裹 `el-form-item` 做校验;
291
+ * 若返回 VNode 则直接渲染,不包裹 form-item(适合纯展示列)。
292
+ */
293
+ render?: ProTableFormColumnRender;
294
+ placeholder?: string;
295
+ /** 列宽(优先级低于 minWidth) */
296
+ width?: number;
297
+ /** 列最小宽度 */
298
+ minWidth?: number;
299
+ /**
300
+ * 透传给单元格组件。`component === 'formatted-number'` 时在此传入
301
+ * `integerDigits`、`decimalPlaces`、`rounding`、`inputLimit` 等(与 FormattedNumberInput 一致)。
302
+ * 支持函数形式,参数为 { row, value, column },返回要合并到组件上的属性。
303
+ */
304
+ componentProps?: Record<string, unknown> | ((params: {
305
+ row: Record<string, unknown>;
306
+ value: unknown;
307
+ column: ProTableFormColumn;
308
+ }) => Record<string, unknown>);
309
+ /** 动态校验规则 */
310
+ dynamicRules?: unknown[] | ((params: {
311
+ row: Record<string, unknown>;
312
+ value: unknown;
313
+ column: ProTableFormColumn;
314
+ }) => unknown[]);
315
+ /** 列级校验规则(会与 dynamicRules/required 合并) */
316
+ rules?: unknown[];
317
+ /**
318
+ * 多级表头子列。
319
+ * 配置后本列作为分组标题行,不渲染数据单元格,子列渲染数据。
320
+ */
321
+ children?: ProTableFormColumnChild[];
322
+ /**
323
+ * 本列是否渲染单元格(默认 true)。children 存在时自动为 false。
324
+ */
325
+ hideInTable?: boolean;
326
+ /** 单元格对齐方式 */
327
+ align?: 'left' | 'center' | 'right';
328
+ /** 表头对齐方式 */
329
+ headerAlign?: 'left' | 'center' | 'right';
330
+ /** 是否固定列 */
331
+ fixed?: boolean | 'left' | 'right';
332
+ /** 单元格样式 */
333
+ cellStyle?: Record<string, string | number>;
334
+ /** 表头单元格样式 */
335
+ headerCellStyle?: Record<string, string | number>;
336
+ /** 单元格 className */
337
+ cellClassName?: string;
338
+ /** 表头单元格 className */
339
+ headerCellClassName?: string;
340
+ /** 是否可排序 */
341
+ sortable?: boolean;
342
+ /** 是否可拖拽调整宽度 */
343
+ resizable?: boolean;
344
+ }
345
+ /** 多级表头子列 */
346
+ export interface ProTableFormColumnChild {
347
+ key: string;
348
+ title: string;
349
+ required?: boolean;
350
+ component?: ProTableFormBuiltInComponent;
351
+ slotName?: string;
352
+ /** 自定义渲染,返回 string(文本)或 VNode(组件) */
353
+ render?: ProTableFormColumnRender;
354
+ placeholder?: string;
355
+ /** 列宽(优先级低于 minWidth) */
356
+ width?: number;
357
+ /** 列最小宽度 */
358
+ minWidth?: number;
359
+ /**
360
+ * 透传给单元格组件。`component === 'formatted-number'` 时在此传入
361
+ * `integerDigits`、`decimalPlaces`、`rounding`、`inputLimit` 等。
362
+ * 支持函数形式,参数为 { row, value, column },返回要合并到组件上的属性。
363
+ */
364
+ componentProps?: Record<string, unknown> | ((params: {
365
+ row: Record<string, unknown>;
366
+ value: unknown;
367
+ column: ProTableFormColumnChild;
368
+ }) => Record<string, unknown>);
369
+ rules?: unknown[];
370
+ /** 动态校验规则 */
371
+ dynamicRules?: unknown[] | ((params: {
372
+ row: Record<string, unknown>;
373
+ value: unknown;
374
+ column: ProTableFormColumnChild;
375
+ }) => unknown[]);
376
+ hideInTable?: boolean;
377
+ /** 单元格对齐方式 */
378
+ align?: 'left' | 'center' | 'right';
379
+ /** 表头对齐方式 */
380
+ headerAlign?: 'left' | 'center' | 'right';
381
+ /** 是否固定列 */
382
+ fixed?: boolean | 'left' | 'right';
383
+ /** 单元格样式 */
384
+ cellStyle?: Record<string, string | number>;
385
+ /** 表头单元格样式 */
386
+ headerCellStyle?: Record<string, string | number>;
387
+ /** 单元格 className */
388
+ cellClassName?: string;
389
+ /** 表头单元格 className */
390
+ headerCellClassName?: string;
391
+ /** 是否可排序 */
392
+ sortable?: boolean;
393
+ /** 是否可拖拽调整宽度 */
394
+ resizable?: boolean;
395
+ }
396
+ /** ProTableForm Props */
397
+ export interface ProTableFormProps {
398
+ modelValue?: Record<string, unknown>[];
399
+ columns: ProTableFormColumn[];
400
+ metricPlaceholder?: string;
401
+ minRows?: number;
402
+ rules?: Record<string, unknown>;
403
+ labelWidth?: string;
404
+ bordered?: boolean;
405
+ /**
406
+ * 表格合并单元格函数,参数同 Element UI el-table span-method。
407
+ * column.property 格式:叶子列 `{colKey}` 或 `{colKey}.{childKey}`;分组列 `{colKey}`。
408
+ */
409
+ spanMethod?: (params: {
410
+ row: Record<string, unknown>;
411
+ column: {
412
+ property: string;
413
+ label: string;
414
+ };
415
+ rowIndex: number;
416
+ columnIndex: number;
417
+ }) => [number, number] | {
418
+ rowspan: number;
419
+ colspan: number;
420
+ } | void;
421
+ /** 表单尺寸 */
422
+ formSize?: 'medium' | 'small' | 'large';
423
+ /** 标签位置 */
424
+ labelPosition?: 'left' | 'right' | 'top';
425
+ /** 表单禁用态 */
426
+ disabled?: boolean;
427
+ /** 斑马纹 */
428
+ stripe?: boolean;
429
+ /** 表格尺寸 */
430
+ size?: 'medium' | 'small' | 'large';
431
+ /** 表格最大高度 */
432
+ maxHeight?: number | string;
433
+ /** 表格固定高度 */
434
+ height?: number | string;
435
+ /** 行 ClassName */
436
+ rowClassName?: string | ((params: {
437
+ row: Record<string, unknown>;
438
+ rowIndex: number;
439
+ }) => string);
440
+ /** 展开行 Keys(树形数据) */
441
+ expandRowKeys?: (string | number)[];
442
+ /** 默认展开所有行 */
443
+ defaultExpandAll?: boolean;
444
+ /** 行点击事件 */
445
+ onRowClick?: (row: Record<string, unknown>, event: Event) => void;
446
+ /** 行双击事件 */
447
+ onRowDblclick?: (row: Record<string, unknown>, event: Event) => void;
448
+ /** 排序变化事件 */
449
+ onSortChange?: (sortInfo: {
450
+ prop: string;
451
+ order: string;
452
+ }) => void;
453
+ /** 展开变化事件 */
454
+ onExpandChange?: (row: Record<string, unknown>, expanded: boolean) => void;
455
+ /** 透传给 el-table 的额外属性(所有上面未覆盖的 el-table 属性均可通过此传入) */
456
+ tableProps?: Record<string, unknown>;
457
+ /** 透传给 el-form 的额外属性 */
458
+ formProps?: Record<string, unknown>;
459
+ }
460
+ /** ProTableForm 操作实例类型 */
461
+ export interface ProTableFormActionType {
462
+ /** 表单校验 */
463
+ validate: () => Promise<boolean>;
464
+ /** 清除校验 */
465
+ clearValidate: (props?: string | string[]) => void;
466
+ /** 新增行 */
467
+ addRow: () => void;
468
+ /** 删除行 */
469
+ removeRow: (index: number) => void;
470
+ /** 获取行列表 */
471
+ getRows: () => Record<string, unknown>[];
472
+ /** 获取 el-table 实例 */
473
+ getTable: () => {
474
+ clearSelection: () => void;
475
+ } | null;
476
+ /** 获取当前行数 */
477
+ getRowCount: () => number;
478
+ /** 获取整个 modelValue */
479
+ getModelValue: () => Record<string, unknown>[];
480
+ /** 设置整个 modelValue(触发 update:modelValue) */
481
+ setModelValue: (val: Record<string, unknown>[]) => void;
482
+ /** 获取 el-form 实例(可用于滚动、聚焦等高级操作) */
483
+ getFormRef: () => FormInstance | null;
484
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aspire-ui/element-component-pro",
3
- "version": "1.0.24",
3
+ "version": "1.0.26",
4
4
  "description": "Element UI 二次封装组件库,基于 Vue 2.7 + TypeScript + setup 语法糖,实现 VbenAdmin 风格的 Pro 组件",
5
5
  "type": "module",
6
6
  "main": "./dist/element-component-pro.umd.js",
@@ -314,7 +314,6 @@ const selectedKeysSet = computed(() => new Set(selectedRows.value.map((r) => r[r
314
314
 
315
315
  /** 显示列 */
316
316
  const displayColumns = computed(() =>{
317
- console.log(innerColumns.value)
318
317
  return innerColumns.value.filter((c) => !c.hideInTable && !c.defaultHidden)
319
318
  })
320
319
 
@@ -0,0 +1,188 @@
1
+ <template>
2
+ <!-- select -->
3
+ <el-select
4
+ v-if="col.component === 'select'"
5
+ :value="value"
6
+ v-bind="cellBind"
7
+ :placeholder="placeholder"
8
+ v-on="mergedEvents('change')"
9
+ >
10
+ <el-option
11
+ v-for="opt in options"
12
+ :key="String(opt.value)"
13
+ :label="opt.label"
14
+ :value="opt.value"
15
+ />
16
+ </el-select>
17
+ <!-- checkbox-group -->
18
+ <el-checkbox-group
19
+ v-else-if="col.component === 'checkbox'"
20
+ :value="value"
21
+ v-bind="cellBind"
22
+ v-on="mergedEvents('change')"
23
+ >
24
+ <el-checkbox
25
+ v-for="opt in options"
26
+ :key="String(opt.value)"
27
+ :label="opt.value"
28
+ >{{ opt.label }}</el-checkbox>
29
+ </el-checkbox-group>
30
+ <!-- radio-group -->
31
+ <el-radio-group
32
+ v-else-if="col.component === 'radio'"
33
+ :value="value"
34
+ v-bind="cellBind"
35
+ v-on="mergedEvents('change')"
36
+ >
37
+ <el-radio
38
+ v-for="opt in options"
39
+ :key="String(opt.value)"
40
+ :label="opt.value"
41
+ >{{ opt.label }}</el-radio>
42
+ </el-radio-group>
43
+ <!-- date-range -->
44
+ <el-date-picker
45
+ v-else-if="col.component === 'date-range'"
46
+ :value="value"
47
+ type="daterange"
48
+ range-separator="至"
49
+ start-placeholder="开始日期"
50
+ end-placeholder="结束日期"
51
+ value-format="yyyy-MM-dd"
52
+ v-bind="cellBind"
53
+ :placeholder="placeholder"
54
+ v-on="mergedEvents('change')"
55
+ />
56
+ <!-- api-select -->
57
+ <ApiSelect
58
+ v-else-if="col.component === 'api-select'"
59
+ :value="value"
60
+ v-bind="cellBind"
61
+ :placeholder="placeholder"
62
+ v-on="mergedEvents('change')"
63
+ />
64
+ <!-- tree-select -->
65
+ <TreeSelect
66
+ v-else-if="col.component === 'tree-select'"
67
+ :value="value"
68
+ v-bind="cellBind"
69
+ :placeholder="placeholder"
70
+ v-on="mergedEvents('change')"
71
+ />
72
+ <!-- 其余 el-* 组件(input / input-number / formatted-number / date-picker / switch / cascader) -->
73
+ <component
74
+ v-else
75
+ :is="cellComp"
76
+ :value="value"
77
+ v-bind="cellBind"
78
+ :placeholder="placeholder"
79
+ v-on="mergedEvents('input')"
80
+ />
81
+ </template>
82
+
83
+ <script setup lang="ts">
84
+ import { computed } from 'vue'
85
+ import ApiSelect from '../ProForm/ApiSelect.vue'
86
+ import TreeSelect from '../ProForm/TreeSelect.vue'
87
+ import FormattedNumberInput from '../ProForm/FormattedNumberInput.vue'
88
+ import type { ProTableFormColumn, ProTableFormColumnChild } from '../types'
89
+
90
+ const props = defineProps<{
91
+ col: ProTableFormColumn | ProTableFormColumnChild
92
+ value: unknown
93
+ /** 当前行数据,用于 dynamicComponentProps 动态求值 */
94
+ row?: Record<string, unknown>
95
+ size?: 'medium' | 'small' | 'large'
96
+ placeholder?: string
97
+ }>()
98
+
99
+ const emit = defineEmits<{ (e: 'update', v: unknown): void }>()
100
+
101
+ const options = computed<Array<{ label: string; value: unknown }>>(() => {
102
+ const staticProps = typeof props.col.componentProps === 'function'
103
+ ? {} : (props.col.componentProps ?? {})
104
+ const opts = staticProps.options
105
+ return Array.isArray(opts) ? opts : []
106
+ })
107
+
108
+ const cellComp = computed(() => {
109
+ const map: Record<string, string> = {
110
+ 'input': 'el-input',
111
+ 'input-number': 'el-input-number',
112
+ 'date-picker': 'el-date-picker',
113
+ 'switch': 'el-switch',
114
+ 'cascader': 'el-cascader',
115
+ }
116
+ if (props.col.component === 'formatted-number') return FormattedNumberInput
117
+ return map[props.col.component as string] || 'el-input'
118
+ })
119
+
120
+ /** All v-bind props, with onXxx event handlers stripped out */
121
+ const cellBind = computed<Record<string, unknown>>(() => {
122
+ let staticProps: Record<string, unknown> = {}
123
+ let dynamicProps: Record<string, unknown> = {}
124
+
125
+ const cp = props.col.componentProps
126
+ if (typeof cp === 'function') {
127
+ dynamicProps = cp({ row: props.row ?? {}, value: props.value, column: props.col as any })
128
+ } else {
129
+ staticProps = cp ?? {}
130
+ }
131
+
132
+ const base: Record<string, unknown> = { size: props.size }
133
+ for (const [key, val] of Object.entries({ ...staticProps, ...dynamicProps })) {
134
+ if (/^on[A-Za-z]/.test(key) && typeof val === 'function') continue
135
+ base[key] = val
136
+ }
137
+ if (props.col.component === 'formatted-number') {
138
+ return { integerDigits: 5, decimalPlaces: 6, rounding: 'round', inputLimit: true, ...base }
139
+ }
140
+ if (['select', 'checkbox', 'radio'].includes(props.col.component as string)) {
141
+ const { options: _opts, ...rest } = base
142
+ void _opts
143
+ return rest
144
+ }
145
+ return base
146
+ })
147
+
148
+ /**
149
+ * Event handlers from componentProps (onXxx → xxx).
150
+ * componentProps 中的 onChange/onInput 等会经过 v-on 绑定,
151
+ * 不再通过 v-bind 直接作为 DOM 属性展开,避免触发 el-form 整行重校验。
152
+ */
153
+ const cellEvents = computed<Record<string, (...args: unknown[]) => unknown>>(() => {
154
+ let staticProps: Record<string, unknown> = {}
155
+ let dynamicProps: Record<string, unknown> = {}
156
+
157
+ const cp = props.col.componentProps
158
+ if (typeof cp === 'function') {
159
+ dynamicProps = cp({ row: props.row ?? {}, value: props.value, column: props.col as any })
160
+ } else {
161
+ staticProps = cp ?? {}
162
+ }
163
+
164
+ const events: Record<string, (...args: unknown[]) => unknown> = {}
165
+ for (const [key, val] of Object.entries({ ...staticProps, ...dynamicProps })) {
166
+ if (/^on[A-Za-z]/.test(key) && typeof val === 'function') {
167
+ const eventName = key[2].toLowerCase() + key.slice(3)
168
+ events[eventName] = val as (...args: unknown[]) => unknown
169
+ }
170
+ }
171
+ return events
172
+ })
173
+
174
+ /**
175
+ * Merges cellEvents (from componentProps) with the internal emit bridge.
176
+ * componentProps listeners fire first, then emit('update') updates the row value.
177
+ */
178
+ const mergedEvents = (internalEvent: 'input' | 'change') => {
179
+ const userHandler = cellEvents.value[internalEvent]
180
+ return {
181
+ ...cellEvents.value,
182
+ [internalEvent]: (arg: unknown) => {
183
+ if (userHandler) userHandler(arg)
184
+ emit('update', arg)
185
+ },
186
+ }
187
+ }
188
+ </script>