Skip to content

Latest commit

 

History

History
1382 lines (1332 loc) · 40.9 KB

File metadata and controls

1382 lines (1332 loc) · 40.9 KB

前端页面 - UI 组件库

改造过的组件库的 API 如下:

图标组件

在 name 和其他组件的图标属性上使用 kebab-case:

<ElIcon name="CopyDocument" />
<ElButton icon="Search" circle />
<ElInput
    modelValue={variable1}
    placeholder="Pick a date"
    suffixIcon="Calendar"
    />

提醒:更多图标列表(icons)及使用说明,需要调用【LoadKnowledge】工具,传入{ showIconList: true }加载【相关知识】

通用基础组件

请注意,使用的时候还是用 TSX 语法!!!

/**
 * 字符串字面量属性类型
 * T, V 仅用于类型检查推导使用,T[多级属性路径] 的类型是否为 V。
 * 实际该类属性绑定时,直接写字段的属性路径字符串,支持多级路径。
 * @example `prop="studentName"`、`titleField="student.name"`、`valueField="student.id"`
 */
type StringPropOf<T, V, K extends nasl.core.String = nasl.core.String> = nasl.core.String;

export class ElTable<T, V, P extends nasl.core.Boolean, M extends nasl.core.Boolean> extends ViewComponent {
    /**
     * 数据
     */
    data: nasl.collection.List<T>;
    /**
     * 分页大小
     */
    pageSize: ElTableOptions<T, V, P, M>['pageSize'];
    /**
     * 当前页数
     */
    currentPage: ElTableOptions<T, V, P, M>['currentPage'];
    /**
     * 排序属性
     */
    order: nasl.core.String;
    /**
     * 排序字段
     */
    sort: nasl.core.String;
    /**
     * 重新加载
     * 清除缓存,重新加载
     */
    reload(): void;
    constructor(options?: Partial<ElTableOptions<T, V, P, M>>);
}
export class ElTableOptions<
    T,
    V,
    P extends nasl.core.Boolean,
    M extends nasl.core.Boolean,
> extends ViewComponentOptions {
    /**
     * 数据源
     * 展示数据的输入源,可设置为数据集对象或者返回数据集的逻辑
     */
    dataSource:
        | {
              list: nasl.collection.List<T>;
              total: nasl.core.Integer;
          }
        | nasl.collection.List<T>;
    /**
     * 数据类型
     * 数据源返回的数据结构的类型,自动识别类型进行展示说明
     */
    dataSchema: T;
    /**
     * 唯一标识
     * 必需。唯一标识一行数据的字段名,来源于 `data` 中的字段。如果是字段嵌套多层,可以设置形如 `item.a.id` 的方法
     */
    rowKey: StringPropOf<T, V>;
    /**
     * 分页
     * 是否显示分页
     */
    pagination: nasl.core.Boolean;
    /**
     * 每页条数选项
     * 每页条数切换器的选项
     */
    pageSizes: nasl.core.String;
    /**
     * 默认每页条数
     */
    defaultPageSize: nasl.core.Integer;
    private pageSize;
    /**
     * 当前页数
     * 当前默认展示在第几页
     */
    defaultCurrentPage: nasl.core.Integer;
    private currentPage;
    /**
     * 显示总条数
     * 是否显示总条数
     */
    showTotal: nasl.core.Boolean;
    /**
     * 显示跳转输入
     * 是否显示跳转页码控制器
     */
    showJumper: nasl.core.Boolean;
    /**
     * 初始化排序字段
     * 设置数据初始化时的排序字段
     */
    defaultField: nasl.core.String;
    /**
     * 初始化排序顺序
     * 设置数据初始化时的排序顺序
     */
    defaultOrder: 'ascending' | 'descending' | null;
    /**
     * 父级值字段
     * 在树形数据中,指定数据父级值的字段
     */
    parentField: StringPropOf<T, V>;
    /**
     * 初始即加载
     * 设置初始时是否立即加载
     */
    initialLoad: nasl.core.Boolean;
    /**
     * 单选行
     * 是否高亮当前行
     */
    highlightCurrentRow: nasl.core.Boolean;
    /**
     * 单选选中值
     * 单选选中值
     */
    selectedValue: V;
    /**
     * 多选选中值
     * 多选选中值
     */
    selectedValues: nasl.collection.List<V>;
    /**
     * 表格尺寸
     * 表格尺寸
     */
    size: 'small' | 'default' | 'large';
    /**
     * 是否显示表格边框
     * 是否显示表格边框
     */
    border: nasl.core.Boolean;
    /**
     * 是否显示斑马纹
     * 是否显示斑马纹
     */
    stripe: nasl.core.Boolean;
    /**
     * 是否显示表头
     * 是否显示表头
     */
    showHeader: nasl.core.Boolean;
    /**
     * 表格布局方式
     * 表格布局方式,`<table>` 元素原生属性。
     */
    tableLayout: 'auto' | 'fixed';
    /**
     * 是否表头吸顶
     * 是否表头吸顶
     */
    sticky: nasl.core.Boolean;
    /**
     * 表头吸顶偏移量
     * 表头吸顶偏移量
     */
    stickyOffset: nasl.core.Integer;
    /**
     * 列配置
     * 列配置
     */
    columnConfig: nasl.core.Boolean;
    /**
     * 合并行或列的计算方法
     * 合并行或列的计算方法
     */
    spanMethod: (item: { row: T; column: any; rowIndex: nasl.core.Integer; columnIndex: nasl.core.Integer }) =>
        | {
              /**
               * @title 合并行数
               */
              rowspan?: nasl.core.Integer;
              /**
               * @title 合并列数
               */
              colspan?: nasl.core.Integer;
          }
        | ((item: { row: T; column: any; rowIndex: nasl.core.Integer; columnIndex: nasl.core.Integer }) => null);
    /**
     * 单元格点击时
     * 单元格点击时触发。
     */
    onCellClick: (event: any) => any;
    /**
     * 选中行变化时
     * 选中行变化时触发
     */
    onSelect: (event: { newSelection: nasl.collection.List<V>; items: nasl.collection.List<T> }) => any;
    /**
     * 全选变化时
     * 全选变化时触发
     */
    onSelectAll: (event: { newSelection: nasl.collection.List<V>; items: nasl.collection.List<T> }) => any;
    /**
     * 分页发生变化时触发
     * 分页发生变化时触发。参数 newDataSource 表示分页后的数据。本地数据进行分页时,newDataSource 和源数据 data 会不一样。泛型 T 指表格数据类型
     */
    onPageChange: (event: any) => any;
    /**
     * 行点击时触发
     * 行点击时触发
     */
    onRowClick: (event: { row: T; index: nasl.core.Integer }) => any;
    /**
     * 当前选中行变化时
     * 当前选中行变化时触发
     */
    onCurrentChange: (event: { row: T }) => any;
    /**
     * 行双击时触发
     * 行双击时触发
     */
    onRowDblclick: (event: any) => any;
    /**
     * 表格内容滚动时触发
     * 表格内容滚动时触发
     */
    onScroll: (event: any) => any;
    /**
     * 数据加载成功时触发
     * 数据加载成功时触发
     */
    onSuccess: () => any;
    /**
     * 表格列
     * 表格列
     */
    slotDefault: () => Array<ViewComponent>;
}
export class ElTableColumn<T, V, P extends nasl.core.Boolean, M extends nasl.core.Boolean> extends ViewComponent {
    constructor(options?: Partial<ElTableColumnOptions<T, V, P, M>>);
}
export class ElTableColumnOptions<
    T,
    V,
    P extends nasl.core.Boolean,
    M extends nasl.core.Boolean,
> extends ViewComponentOptions {
    /**
     * 列类型
     * 支持序号列、单/多选、树形列和编辑列切换,序号列支持按照数字排序。选择编辑列需要先设置列字段。
     */
    type: 'normal' | 'selection' | 'expand' | 'index' | 'editable';
    /**
     * 换页继续编号
     * 换页后,继续上一页的列序号进行编号
     */
    autoIndex: nasl.core.Boolean;
    /**
     * 列标题
     * 列标题用于自定义列标题
     */
    label: nasl.core.String;
    /**
     * 列字段
     * data 项中的字段
     */
    prop: StringPropOf<T, any>;
    /**
     * 排序
     * 设置该列是否可以排序
     */
    sortable: 'none' | 'custom';
    /**
     * 固定列
     * 该列是否固定。左侧固定列需要从第一列到当前固定列之间的列都是固定列。右侧固定列需要最后一列到当前固定列之间的列都是固定列。
     */
    isFixed: nasl.core.Boolean;
    /**
     * 固定列位置
     * 该列是否固定。左侧固定列需要从第一列到当前固定列之间的列都是固定列。右侧固定列需要最后一列到当前固定列之间的列都是固定列。
     */
    fixed: 'left' | 'right';
    /**
     * 是否允许调整列宽
     * 是否允许调整列宽,需要打开表格的边框属性
     */
    resizable: nasl.core.Boolean;
    /**
     * 编辑列变化时
     * 编辑列变化时触发
     */
    onEditChange: (event: { row: T; $index: nasl.core.Integer; cellIndex: nasl.core.Integer }) => any;
    /**
     * 单元格
     * 对单元格的数据展示进行自定义
     */
    slotDefault: (current: {
        item: T;
        index: nasl.core.Integer;
        rowIndex: nasl.core.Integer;
        columnIndex: nasl.core.Integer;
        isPreview: nasl.core.Boolean;
    }) => Array<ViewComponent>;
    /**
     * 标题
     * 对标题进行自定义
     */
    slotHeader: () => Array<ViewComponent>;
}
export class ElTableColumnDynamic<
    T,
    V,
    P extends nasl.core.Boolean,
    M extends nasl.core.Boolean,
    T1,
> extends ViewComponent {
    constructor(options?: Partial<ElTableColumnDynamicOptions<T, V, P, M, T1>>);
}
export class ElTableColumnDynamicOptions<
    T,
    V,
    P extends nasl.core.Boolean,
    M extends nasl.core.Boolean,
    T1,
> extends ViewComponentOptions {
    /**
     * 数据源
     * 展示数据的输入源,可设置为数据集对象或者返回数据集的逻辑
     */
    dataSource:
        | {
              list: nasl.collection.List<T1>;
              total: nasl.core.Integer;
          }
        | nasl.collection.List<T1>;
    /**
     * 数据类型
     * 数据源返回的数据结构的类型,自动识别类型进行展示说明
     */
    dataSchema: T1;
    /**
     * 列字段
     * data 项中的字段
     */
    prop: StringPropOf<T1, any>;
    /**
     * 排序
     * 设置该列是否可以排序
     */
    sortable: 'none' | 'custom';
    /**
     * 固定列
     * 该列是否固定。左侧固定列需要从第一列到当前固定列之间的列都是固定列。右侧固定列需要最后一列到当前固定列之间的列都是固定列。
     */
    isFixed: nasl.core.Boolean;
    /**
     * 固定列位置
     * 该列是否固定。左侧固定列需要从第一列到当前固定列之间的列都是固定列。右侧固定列需要最后一列到当前固定列之间的列都是固定列。
     */
    fixed: 'left' | 'right';
    /**
     * 是否允许调整列宽
     * 是否允许调整列宽,需要打开表格的边框属性
     */
    resizable: nasl.core.Boolean;
    /**
     * 单元格
     * 对单元格的数据展示进行自定义
     */
    slotDefault: (current: Current<T>) => Array<ViewComponent>;
    /**
     * 标题
     * 对标题进行自定义
     */
    slotHeader: () => Array<ViewComponent>;
}

export class ElTabs<T, V> extends ViewComponent {
    /**
     * 重新加载
     * 清除缓存,重新加载
     */
    reload(): void;
    constructor(options?: Partial<ElTabsOptions<T, V>>);
}
export class ElTabsOptions<T, V> extends ViewComponentOptions {
    /**
     * 数据源
     * 展示数据的输入源,可设置为集合类型变量(List<T>)或输出参数为集合类型的逻辑。
     */
    dataSource:
        | {
              list: nasl.collection.List<T>;
              total: nasl.core.Integer;
          }
        | nasl.collection.List<T>;
    /**
     * 数据类型
     * 数据源返回的数据结构的类型,自动识别类型进行展示说明
     */
    dataSchema: T;
    /**
     * 文本字段
     * 集合的元素类型中,用于显示文本的属性名称
     */
    titleField: StringPropOf<T, nasl.core.String>;
    /**
     * 值字段
     * 集合的元素类型中,用于标识选中值的属性
     */
    valueField: StringPropOf<T, V>;
    /**
     * 标签页属性设置
     * 开启数据源后,设置每个标签页属性
     */
    tabPaneProps: (current: Current<T>) => {
        disabled: nasl.core.Boolean;
        closable: nasl.core.Boolean;
        lazy: nasl.core.Boolean;
    };
    /**
     * 选中值
     * 绑定值,选中选项卡的 name
     */
    modelValue: nasl.core.String;
    /**
     * 风格样式
     * 风格样式
     */
    type: '' | 'card' | 'border-card';
    /**
     * 可关闭
     * 标签页是否可关闭
     */
    closable: nasl.core.Boolean;
    /**
     * 可增加
     * 标签页是否可增加
     */
    addable: nasl.core.Boolean;
    /**
     * 可增加且可关闭
     * 标签是否同时可增加和关闭
     */
    editable: nasl.core.Boolean;
    /**
     * 添加按钮图标
     * 自定义添加按钮图标
     */
    addIcon: nasl.core.String;
    /**
     * 选项卡所在位置
     * 选项卡所在位置
     */
    tabPosition: 'top' | 'right' | 'bottom' | 'left';
    /**
     * 标签的宽度是否自撑开
     * 标签的宽度是否自撑开
     */
    stretch: nasl.core.Boolean;
    /**
     * 切换标签之前的逻辑
     * 切换标签之前的钩子,若返回 false 则阻止切换。
     */
    beforeLeave: (activeName: nasl.core.String, oldActiveName: nasl.core.String) => nasl.core.Boolean;
    /**
     * 改变时
     * activeName 改变时触发
     */
    onTabChange: (name: nasl.core.String) => void;
    /**
     * 点击标签页
     * tab 被选中时触发
     */
    onTabClick: (event: {
        active: nasl.core.Boolean;
        loaded: nasl.core.Boolean;
        isClosable: nasl.core.Boolean;
        value: nasl.core.String;
    }) => void;
    /**
     * 点击移除按钮时
     * 点击移除按钮后触发
     */
    onTabRemove: (event: nasl.core.String) => void;
    /**
     * 点击新增按钮
     * 点击 tabs 的新增按钮后触发
     */
    onTabAdd: (event: {}) => void;
    /**
     * 点击新增按钮或关闭
     * 点击 tabs 的新增按钮或 tab 被关闭后触发
     */
    onEdit: (event: { value: nasl.core.String; action: 'add' | 'remove' }) => void;
    /**
     * 标签页
     * 内容
     */
    slotDefault: () => Array<ViewComponent>;
    /**
     * 标签页标题
     * 标签页标题
     */
    slotLabel: (current: Current<T>) => Array<ViewComponent>;
    /**
     * 标签页内容
     * 标签页内容
     */
    slotContent: (current: Current<T>) => Array<ViewComponent>;
}
export class ElTabPane extends ViewComponent {
    constructor(options?: Partial<ElTabPaneOptions>);
}
export class ElTabPaneOptions extends ViewComponentOptions {
    /**
     * 值
     * 与选项卡绑定值对应的标识符
     */
    name: nasl.core.String | nasl.core.Integer;
    /**
     * 是否禁用
     * 是否禁用
     */
    disabled: nasl.core.Boolean;
    /**
     * 标签是否可关闭
     * 标签是否可关闭
     */
    closable: nasl.core.Boolean;
    /**
     * 标签是否延迟渲染
     * 标签是否延迟渲染
     */
    lazy: nasl.core.Boolean;
    /**
     * 标签页内容
     * 标签页内容
     */
    slotDefault: () => Array<ViewComponent>;
    /**
     * 标签页标题
     * 标签页标题
     */
    slotLabel: () => Array<ViewComponent>;
}

export class ElForm extends ViewComponent {
    /**
     * 重置表单
     * 表单里面没有重置按钮<button type="reset" />时可以使用该方法,默认重置全部字段为空,该方法会触发 reset 事件。如果表单属性 resetType='empty' 或者 reset.type='empty' 会重置为空;如果表单属性 resetType='initial' 或者 reset.type='initial' 会重置为表单初始值。
     */
    resetForm(): void;
    /**
     * 校验函数
     * 校验函数,包含错误文本提示等功能
     */
    validated(): {
        valid: nasl.core.Boolean;
    };
    constructor(options?: Partial<ElFormOptions>);
}
export class ElFormOptions extends ViewComponentOptions {
    /**
     * 标签布局
     * 选择表单标签的对齐方式
     */
    labelPosition: 'left' | 'right' | 'top';
    /**
     * 行内布局
     * 是否使用行内布局模式
     */
    inline: nasl.core.Boolean;
    /**
     * 隐藏必填标记
     * 是否隐藏必填字段的星号标记
     */
    hideRequiredAsterisk: nasl.core.Boolean;
    /**
     * 星号位置
     * 必填标记星号的位置
     */
    requireAsteriskPosition: 'left' | 'right';
    /**
     * 显示错误信息
     * 是否显示表单验证错误信息
     */
    showMessage: nasl.core.Boolean;
    /**
     * 行内错误信息
     * 是否在字段右侧显示错误信息
     */
    inlineMessage: nasl.core.Boolean;
    /**
     * 自动滚动
     * 验证失败时是否自动滚动到错误字段
     */
    scrollToError: nasl.core.Boolean;
    /**
     * 禁用状态
     * 是否禁用整个表单
     */
    disabled: nasl.core.Boolean;
    /**
     * 预览模式
     * 是否启用预览模式
     */
    preview: nasl.core.Boolean;
    /**
     * 表单尺寸
     * 选择表单的整体尺寸
     */
    size: 'small' | 'medium' | 'large' | '';
    /**
     * 标签宽度
     * 设置表单标签的宽度
     */
    labelWidth: nasl.core.String | nasl.core.Decimal;
    /**
     * 表单内容
     * 插入表单项
     */
    slotDefault: () => Array<ViewComponent>;
}
export class ElFormItemPro extends ViewComponent {
    constructor(options?: Partial<ElFormItemProOptions>);
}
/**
 * 注意 在 <Form> 中 <FormItemPro> 已经和子元素 <Input> <Select> 等合并为 <FormInput> <FormSelect>,属性合在一起。
 */
export class ElFormItemProOptions extends ViewComponentOptions {
    /**
     * 标签宽度
     * 可以整体设置标签宽度,优先级高于表单项
     */
    labelWidth: nasl.core.String | nasl.core.Decimal;
    /**
     * 验证规则
     * 表单字段校验规则。
     */
    rules: nasl.collection.List<nasl.validation.ValidationRule>;
    /**
     * 验证触发方式
     * 验证逻辑的触发方式
     */
    trigger: 'blur' | 'change';
    /**
     * 必填标记
     * 是否为必填项,并显示必填标记
     */
    isRequired: nasl.core.Boolean;
    /**
     * 标签
     * 字段标签名称。
     */
    slotLabel: () => Array<ViewComponent>;
    /**
     * 表单组件
     * 表单组件
     */
    slotDefault: () => Array<ViewComponent>;
}

export class ElSelect<T, V, P extends nasl.core.Boolean, M extends nasl.core.Boolean, C> extends ViewComponent {
    /**
     * 重新加载
     * 清除缓存,重新加载
     */
    reload(): void;
    constructor(options?: Partial<ElSelectOptions<T, V, P, M, C>>);
}
export class ElSelectOptions<
    T,
    V,
    P extends nasl.core.Boolean,
    M extends nasl.core.Boolean,
    C,
> extends ViewComponentOptions {
    /**
     * 数据源
     * 设置选择器的数据来源,支持绑定集合类型变量或返回集合的逻辑
     */
    dataSource:
        | {
              list: nasl.collection.List<T>;
              total: nasl.core.Integer;
          }
        | nasl.collection.List<T>;
    /**
     * 数据类型
     * 数据源中每个数据项的类型定义,用于类型推导和属性选择
     */
    dataSchema: T;
    /**
     * 文本字段
     * 指定数据项中哪个字段作为选项的显示文本
     */
    textField: StringPropOf<T, any>;
    /**
     * 值字段
     * 指定数据项中哪个字段作为选项的值
     */
    valueField: StringPropOf<T, V>;
    /**
     * 描述字段
     * 指定数据项中哪个字段作为选项的描述文本
     */
    descriptionField: StringPropOf<T, any>;
    /**
     * 选中值
     * 当前选中的选项值,支持双向绑定
     */
    modelValue: M extends true ? nasl.collection.List<V> : V;
    /**
     * 选中数据
     * 当前选中选项的完整数据对象
     */
    selectedValuesData: nasl.collection.List<{
        label: nasl.core.String;
        value: V;
    }>;
    /**
     * 多选模式
     * 是否允许多选选项
     */
    multiple: M;
    /**
     * 折叠标签
     * 多选时是否折叠显示标签
     */
    collapseTags: nasl.core.Boolean;
    /**
     * 折叠提示
     * 折叠标签时是否显示提示信息
     */
    collapseTagsTooltip: nasl.core.Boolean;
    /**
     * 虚拟滚动
     * 是否开启虚拟滚动优化
     */
    virtualize: nasl.core.Boolean;
    /**
     * 占位符
     * 选择框为空时显示的提示文本
     */
    placeholder: nasl.core.String;
    /**
     * 组件尺寸
     * 选择器组件的尺寸大小
     */
    size: 'small' | 'default' | 'large';
    /**
     * 无数据文本
     * 没有选项时显示的文字
     */
    noDataText: nasl.core.String;
    /**
     * 可清空
     * 是否允许清空已选择的选项
     */
    clearable: nasl.core.Boolean;
    /**
     * 可搜索
     * 是否允许搜索选项
     */
    filterable: nasl.core.Boolean;
    /**
     * 禁用状态
     * 是否禁用选择器组件
     */
    disabled: nasl.core.Boolean;
    /**
     * 选中值变化时
     * 选中值变化时触发。
     */
    onChange: (event: M extends true ? (C extends '' ? nasl.collection.List<V> : nasl.core.String) : V) => any;
    /**
     * 清空时
     * 清空时触发
     */
    onClear: (event: any) => any;
    /**
     * 下拉框显示或隐藏时
     * 下拉框显示或隐藏时触发
     */
    onVisibleChange: (event: any) => any;
    /**
     * 失去焦点时
     * 失去焦点时触发
     */
    onBlur: (event: any) => any;
    /**
     * 获得焦点时
     * 获得焦点时触发
     */
    onFocus: (event: any) => any;
    /**
     * Default
     * 内容
     */
    slotDefault: () => Array<ViewComponent>;
}
export class ElFormSelect<T, V, P extends nasl.core.Boolean, M extends nasl.core.Boolean, C> extends ViewComponent {
    constructor(
        options?: Partial<
            ElFormSelectOptions<T, V, P, M, C> &
                ElFormItemProOptions &
                Omit<ElSelectOptions<T, V, P, M, C>, keyof ElFormItemProOptions>
        >
    );
    /**
     * 重新加载
     * 清除缓存,重新加载
     */
    reload(): void;
}
export class ElFormSelectOptions<
    T,
    V,
    P extends nasl.core.Boolean,
    M extends nasl.core.Boolean,
    C,
> extends ViewComponentOptions {}

@Component({
    title: '组件列表',
    icon: 'forcom',
    description: '组件列表',
    group: 'Table',
})
export class ElListComponents<T, V, P extends nasl.core.Boolean, M extends nasl.core.Boolean, C> extends ViewComponent {
    /**
     * 数据
     */
    data: nasl.collection.List<T>;
    /**
     * 重新加载
     * 清除缓存,重新加载
     */
    reload(): void;
    constructor(options?: Partial<ElListComponentsOptions<T, V, P, M, C>>);
}

/**
 * 数据选择器:<ElFormSelect modelValue={$sync(someValue)} dataSource={app.logics.loadStudents} textField="student.name" valueField="student.id" placeholder="请选择学生" clearable={true} />
 *
 * 枚举选择器:<ElFormSelect modelValue={$sync(someValue)} dataSource={nasl.util.EnumToList<app.enums.SomeEnum>()} textField="text" valueField="item" placeholder="请选择XxxE" clearable={true} />
 *
 * 注意!!!ElFormSelect 不要用 slotLabel。始终用 textField!!
 */
export class ElListComponentsOptions<
    T,
    V,
    P extends nasl.core.Boolean,
    M extends nasl.core.Boolean,
    C,
> extends ViewComponentOptions {
    /**
     * 表单模式
     * 是否以表单模式显示
     */
    formMode: nasl.core.Boolean;
    /**
     * 数据源
     * 设置组件列表的数据来源,支持绑定集合类型变量或返回集合的逻辑
     */
    dataSource: nasl.collection.List<T> | { list: nasl.collection.List<T>; total: nasl.core.Integer };
    /**
     * 数据类型
     * 数据源中每个数据项的类型定义,用于类型推导和属性选择
     */
    dataSchema: T;
    /**
     * 表单值
     * 组件列表的表单值
     */
    model: nasl.collection.List<T>;
    /**
     * 唯一标识
     * 指定数据项中哪个字段作为列表项的唯一标识
     */
    idField: StringPropOf<T, any>;
    /**
     * 文本字段
     * 指定数据项中哪个字段作为列表项的显示文本
     */
    textField: StringPropOf<T, any>;
    /**
     * 列数
     * 设置每行显示的组件数量
     */
    column: nasl.core.Decimal | nasl.core.Integer;
    /**
     * 均分宽度
     * 是否让每个组件平均分配宽度
     */
    equalWidth: nasl.core.Boolean;
    /**
     * 分页模式
     * 选择分页的显示模式
     */
    pagination: 'none' | 'autoMore' | 'page';
    /**
     * 显示总条数
     * 是否在分页组件中显示总条数
     */
    showTotal: nasl.core.Boolean;
    /**
     * 显示跳转
     * 是否显示页码跳转输入框
     */
    showJumper: nasl.core.Boolean;
    /**
     * 当前页
     * 当前显示的页码
     */
    currentPage: nasl.core.Integer;
    /**
     * 每页条数
     * 每页显示的数据条数
     */
    pageSize: nasl.core.Integer;
    /**
     * 每页数量选项
     * 每页条数选择器的可选值
     */
    pageSizes: nasl.collection.List<nasl.core.Integer>;
    /**
     * 分页背景色
     * 是否为分页按钮添加背景色
     */
    paginationBackground: nasl.core.Boolean;
    /**
     * 分页尺寸
     * 分页组件的尺寸大小
     */
    paginationSize: 'small' | 'default' | 'large';
    /**
     * 选择模式
     * 设置列表项的选择模式
     */
    selectionMode: 'none' | 'single' | 'multiple';
    /**
     * 可清除
     * 是否允许清除已选中的项
     */
    clearable: nasl.core.Boolean;
    /**
     * 是否范围
     * 是否支持范围选择
     */
    isRange: nasl.core.Boolean;
    /**
     * 选中值
     * 当前选中的列表项值
     */
    modelValue: M extends true ? nasl.collection.List<V> : V;
    /**
     * 行间距
     * 设置组件行与行之间的间距
     */
    rowGap: nasl.core.Decimal | nasl.core.Integer;
    /**
     * 列间距
     * 设置组件列与列之间的间距
     */
    columnGap: nasl.core.Decimal | nasl.core.Integer;
    /**
     * 页码改变时
     * 当前页码改变时触发
     */
    onPageChange: (event: { page: nasl.core.Integer; pageSize: nasl.core.Integer }) => any;
    /**
     * 每页数量改变时
     * 每页显示条数改变时触发
     */
    onSizeChange: (event: { page: nasl.core.Integer; pageSize: nasl.core.Integer }) => any;
    /**
     * 选中改变时
     * 选中值改变时触发
     */
    onSelectionChange: (event: { value: any; items: nasl.collection.List<T> }) => any;
    /**
     * 默认
     * 内容自定义
     */
    slotDefault: (current: Current<T>) => Array<ViewComponent>;
}

/**
 * @example
 * 使用 dataSource 时,只用于展示。
<ElListComponents dataSource={app.logics.loadStudents} idField="student.id">
{(current) => <ElText text={current.item.student.name} />}
</ElListComponents>

 * @example
 * 使用 dataSource 时,只用于展示。
<ElListComponents dataSource={studentList} idField="student.id">
{(current) => <ElText text={current.item.student.name} />}
</ElListComponents>

 * @example
 * 自定义pageSize=12,必须在pageSizes中包含12
<ElListComponents dataSource={app.logics.loadStudents} idField="student.id" pageSize={12} pageSizes="[10, 12, 20, 50]">
{(current) => <ElText text={current.item.student.name} />}
</ElListComponents>

 * @example
 * 需要对列表中的值进行修改时,如用双向绑定或赋值修改 current.item.xxx 的值,ElListComponents 请切换成表单模式,并且需要将“数据源”属性切换为使用“model”属性
<ElListComponents
  formMode={true}
  model={leaveDays}
  slotDefault={(current) => (
    <ElFlex style="width: 100%">
      <ElFormSelect
        modelValue={$sync(current.item.halfDayLeaveType)}
      ></ElFormSelect>
      <ElButton
        text="修改"
        onClick={function click(event) {
          current.item.halfDayLeaveType = app.enums.HalfDayLeaveType["MORNING"];
        }}
      />
    </ElFlex>
  )}
/>;

 */

@Component({
    title: '弹性布局',
    icon: 'linear-layout',
    description: '内部元素按照一定的规则布局',
    group: 'Layout',
})
export class ElFlex extends ViewComponent {
    constructor(options?: Partial<ElFlexOptions>) {
        super();
    }
}

export class ElFlexOptions extends ViewComponentOptions {
    @Prop<ElFlexOptions, 'mode'>({
        group: '样式属性',
        title: '布局模式',
        description: '设置布局模式',
        bindHide: true,
        tabKind: 'style',
        setter: {
            concept: 'CapsulesSetter',
            options: [
                {
                    title: '块级',
                    icon: 'layout-block',
                    tooltip: '块级布局',
                },
                {
                    title: '弹性',
                    icon: 'layout-flex',
                    tooltip: '弹性布局',
                },
            ],
        },
        onChange: [
            {
                clear: ['justify', 'alignment', 'wrap', 'layout'],
            },
        ],
    })
    mode: 'block' | 'flex' = 'flex';

    @Prop<ElFlexOptions, 'direction'>({
        group: '主要属性',
        title: '主轴方向',
        docDescription: `横向:内部子元素进行横向排布,建议内部子元素使用行内布局。
    纵向:内部子元素进行纵向排布,建议内部子元素使用块级布局。`,
        bindHide: true,
        setter: {
            concept: 'CapsulesSetter',
            options: [
                { title: '横向排列', icon: 'flex-horizontal', tooltip: '横向' },
                { title: '纵向排列', icon: 'flex-vertical', tooltip: '纵向' },
            ],
        },
        onChange: [
            { update: { alignment: 'start', justify: 'start' }, if: (_) => _ === 'horizontal' },
            { update: { alignment: 'stretch', justify: 'start' }, if: (_) => _ === 'vertical' },
        ],
        tabKind: 'style',
    })
    direction: 'horizontal' | 'vertical' = 'horizontal';

    @Prop<ElFlexOptions, 'justify'>({
        group: '主要属性',
        title: '横轴对齐',
        docDescription: `主轴方向为横向时:支持左对齐、居中对齐、右对齐、平均分布(两端不留空)、平均分布,其中平均分布仅在弹性布局模式下展示。
    主轴方向为纵向时:支持左对齐、居中对齐、右对齐、占满容器宽度,其中占满容器宽度仅在弹性布局模式下展示。`,
        bindHide: true,
        setter: {
            concept: 'CapsulesSetter',
            options: [
                {
                    title: '左对齐',
                    icon: 'horizontal-justify-start',
                    tooltip: '左对齐',
                },
                {
                    title: '居中对齐',
                    icon: 'horizontal-justify-center',
                    tooltip: '居中对齐',
                },
                {
                    title: '右对齐',
                    icon: 'horizontal-justify-end',
                    tooltip: '右对齐',
                },
                {
                    title: '平均分布(两端不留空)',
                    icon: 'horizontal-justify-space-between',
                    tooltip: '平均分布(两端不留空)',
                },
                {
                    title: '平均分布',
                    icon: 'horizontal-justify-space-around',
                    tooltip: '平均分布',
                },
            ],
        },
        tabKind: 'style',
        onChange: [
            { update: { gutter: 12 }, if: (_) => _ === 'space-between' },
            { update: { gutter: 12 }, if: (_) => _ === 'space-around' },
        ],
        if: (_) => _.mode === 'flex',
    })
    justify: 'start' | 'center' | 'end' | 'space-between' | 'space-around' = 'start';

    @Prop<ElFlexOptions, 'alignment'>({
        group: '主要属性',
        title: '纵轴对齐',
        docDescription: `主轴方向为横向时:支持顶对齐、垂直居中、底对齐、行内文字基线对齐、占满容器高度。
    主轴方向为纵向时:支持顶对齐、垂直居中、底对齐、平均分布(两端不留空)、平均分布。`,
        bindHide: true,
        setter: {
            concept: 'CapsulesSetter',
            options: [
                {
                    title: '顶对齐',
                    icon: 'horizontal-alignment-start',
                    tooltip: '顶对齐',
                },
                {
                    title: '垂直居中',
                    icon: 'horizontal-alignment-center',
                    tooltip: '垂直居中',
                },
                {
                    title: '底对齐',
                    icon: 'horizontal-alignment-end',
                    tooltip: '底对齐',
                },
                {
                    title: '行内文字基线对齐',
                    icon: 'horizontal-alignment-baseline',
                    tooltip: '行内文字基线对齐',
                },
                {
                    title: '占满容器高度',
                    icon: 'horizontal-alignment-stretch',
                    tooltip: '占满容器高度',
                },
            ],
        },
        tabKind: 'style',
        if: (_) => _.mode === 'flex',
    })
    alignment: 'start' | 'center' | 'end' | 'baseline' | 'stretch' = 'start';

    @Prop<ElFlexOptions, 'wrap'>({
        group: '主要属性',
        title: '换行',
        description: '设置弹性布局下子元素总宽度超出父级时子元素是否换行展示',
        docDescription: '支持控制弹性布局模式下,子元素总宽度超过父级时是否换行展示,默认开启。',
        setter: {
            concept: 'SwitchSetter',
        },
        tabKind: 'style',
        if: (_) => _.mode === 'flex',
    })
    wrap: nasl.core.Boolean = true;

    @Prop<ElFlexOptions, 'gutter'>({
        group: '样式属性',
        title: '内容间隙',
        description: '内容块间隙大小',
        docDescription: '布局内各个组件之间的间隔,通常有收缩、无、小、正常、大,默认为正常。',
        tabKind: 'style',
        setter: {
            concept: 'NumberInputSetter',
        },
        if: (_) =>
            _.mode === 'block' || (_.mode === 'flex' && _.justify !== 'space-between' && _.justify !== 'space-around'),
    })
    gutter: nasl.core.Decimal | nasl.core.Integer = 12;
}

/**
 * @example
<ElDatePicker ref="el_date_picker_1_1" type="datetime" placeholder="请选择日期时间" modelValue={$sync(dateTime_1_1)} />;

 * @example
<ElDatePicker ref="el_date_picker_2_2" type="date" placeholder="请选择日期" modelValue={$sync(date_2_2)} />;

 * @example
<ElDatePicker ref="el_date_picker_3_1" type="year" placeholder="请选择年份" modelValue={$sync(dateTime_3_1)} />;

 * @example
<ElDatePicker ref="el_date_picker_6_1" type="daterange" placeholder="请选择日期范围" startValue={$sync(date_6_1)} endValue= {$sync(date_6_2)} />;

 * @example
<ElDatePicker ref="el_date_picker_7_1" type="monthrange" placeholder="请选择月份范围" startValue={$sync(dateTime_7_1)} endValue= {$sync(dateTime_7_2)} />;
 */

@Component({
    title: '日期选择器',
    icon: 'date-picker',
    description: '用于选择某一具体日期或某一段日期区间。',
    group: 'Selector',
})
export class ElDatePicker<T, V, P extends nasl.core.Boolean, M extends nasl.core.Boolean, C, DT> extends ViewComponent {
    constructor(options?: Partial<ElDatePickerOptions<T, V, P, M, C, DT>>);
}
export class ElDatePickerOptions<
    T,
    V,
    P extends nasl.core.Boolean,
    M extends nasl.core.Boolean,
    C,
    DT extends
        | 'datetime'
        | 'date'
        | 'year'
        | 'month'
        | 'week'
        | 'datetimerange'
        | 'daterange'
        | 'yearrange'
        | 'monthrange',
> extends ViewComponentOptions {
    /**
     * 选中值
     * 当前选中的日期值
     */
    modelValue: DT extends 'date'
        ? nasl.core.Date
        : DT extends 'datetime' | 'year' | 'month' | 'week'
          ? nasl.core.DateTime
          : null;
    /**
     * 起始值
     * 区间选择的开始日期
     */
    startValue: DT extends 'daterange'
        ? nasl.core.Date
        : DT extends 'datetimerange' | 'yearrange' | 'monthrange'
          ? nasl.core.DateTime
          : null;
    /**
     * 结束值
     * 结束日期
     */
    endValue: DT extends 'daterange'
        ? nasl.core.Date
        : DT extends 'datetimerange' | 'yearrange' | 'monthrange'
          ? nasl.core.DateTime
          : null;
    /**
     * 显示类型
     * 显示类型
     */
    type: 'year' | 'month' | 'date' | 'datetime' | 'week' | 'datetimerange' | 'daterange' | 'monthrange' | 'yearrange';
    /**
     * ...
     * 其余属性参考 Element-Plus
     */
    /**
     * 值改变时
     * 用户确认选定的值时触发
     */
    onChange: (modelValue: M extends true ? nasl.collection.List<nasl.core.Date> : nasl.core.Date) => void;
    /**
     * ...
     * 其余事件参考 Element-Plus
     */
}

请注意,使用的时候还是用 TSX 语法!!!

组件示例

除了 ElText, ElButton, ElLink,ElTag 本身有 text 属性,其他组件尽量使用 slotTitle, slotLabel 和 slotDefault (具体用哪个需要看 API 文档),与 ElText 组件组合来设置文本内容。

<ElAlert type="info"
    slotTitle={() => <ElText text="公告" />}
    slotDefault={() => <ElText text="这是一条提示信息" />}
    />

图表组件(CwChartJs)

CwChartJs 用于实现常规图表展示能力,支持的图表类型如下:

图表类型 说明
Line 折线图(支持多线、曲线、填充区域)
Bar 柱状图/条形图(垂直、水平、堆叠)
Radar 雷达图/蜘蛛图
Doughnut 甜甜圈图
Pie 饼图
Polar Area 极地区域图
Bubble 气泡图(三维数据:x, y, radius)
Scatter 散点图

可用的组件列表:

请尽量使用以下组件:

ElAffix, ElAlert, ElBacktop, ElButton, ElCard, ElDialog, ElFlex, ElForm, ElPageHeader, ElRouterView, ElSteps, ElStep, ElTable, ElTableColumn, ElTabs, ElTabPane, ElText, ElAbsoluteLayout, ElBreadcrumb, ElBreadcrumbItem, ElCalendar, ElCascader, ElFormCascader, ElDropdown, ElDropdownItem, ElIframe, ElInput, ElFormInput, ElSelect, ElOption, ElFormSelect, ElCarousel, ElCarouselItem, ElCollapse, ElCollapseItem, ElDatePicker, ElFormDatePicker, ElDrawer, ElListComponents, ElMenu, ElSubMenu, ElMenuItem, ElMenuItemGroup, ElRow, ElCol, ElIcon, ElMention, ElFormMention, ElMultiLayout, ElMultiLayoutItem, ElRadioGroup, ElRadio, ElFormRadioGroup, ElTag, ElCheckTag, ElBadge, ElSwitch, ElFormSwitch, ElTreeSelect, ElFormTreeSelect, ElCheckboxGroup, ElCheckbox, ElFormCheckboxGroup, ElPopover, ElDescriptions, ElDescriptionsItem, ElLoading, ElRate, ElFormRate, ElTooltip, ElTree, ElImage, ElImageViewer, ElPagination, ElProgress, ElScrollbar, ElTimePicker, ElFormTimePicker, ElTimeSelect, ElFormTimeSelect, ElTransfer, ElFormTransfer, ElUpload, ElFormUpload, ElTimeline, ElTimelineItem, ElWatermark, ElDivider, ElAnchor, ElAnchorLink, ElAnchorItem, ElResult, ElInputNumber, ElFormInputNumber, ElInputTag, ElFormInputTag, ElLink, ElSlider, ElFormSlider, uilibs.cw_chart_js.components.CwChartJs

其中 ElFlex 可以当 div 或 span 使用。ElMultiLayout 和 ElMultiLayoutItem 都继承自 ElFlex,与 ElFlex api 相同。

  • 提醒:更多上传组件(ElUpload)的定义和使用说明,需要调用【LoadKnowledge】工具,传入{ useUpload: true }加载【相关知识】
  • 提醒:更多级联选择器(ElCascader)的定义和使用说明,需要调用【LoadKnowledge】工具,传入{ useCascader: true }加载【相关知识】
  • 提醒:更多日历(ElCalendar)的定义、约束与使用示例,需要调用【LoadKnowledge】工具,传入{ useCalendar: true }加载【相关知识】

扩展组件库使用示例

<uilibs.map_location.components.MapLocation
    value={variable1} showCoordinates={true} showAddress={true} />

提醒:更多扩展组件的定义和使用说明,需要调用【LoadKnowledge】工具,传入{ useFrontendDependencies: true }加载【相关知识】

注意

  • 如果需求和技术设计中提到的扩展组件库和特殊组件确实存在,请认真使用并实现相关功能;
  • 如果确实不存在,不要硬写,你也无法自行补充。请用基础组件简单模拟占位实现即可。
- uilibs.xxx.ts 文件为外部依赖,仅可引用,不可修改 - 使用组件、逻辑调用和数据结构时,一定要写全命名空间,如 `{外部依赖类型(复数)}.${扩展组件库名}.{components|logics|structures}.${组件名|逻辑名|数据结构名}` - 使用时,一定要用 tsx 的语法,不要用 new Class() 的方式。 - **前端页面 - 表单中的验证规则**:请参考 nasl-book/K010-frontend-view--validation-rules-in-form.md 文件