Skip to content

TS数据结构

本文档详细介绍了 fcDesigner 中各个核心数据结构的 TypeScript 定义。这些数据结构定义了如何生成组件、拖拽组件、配置设计器等。通过理解这些数据结构,你可以自定义和扩展设计器的功能,以满足不同的业务需求。

组件生成规则

组件的 JSON 数据结构

Rule 是描述组件生成规则的核心数据结构。每个组件都有一个唯一的 _fc_id 标识符和其他属性,用于定义组件的类型、样式、事件、验证规则等。

ts
type Rule = {
    //规则唯一值
    _fc_id: string;
    //拖拽规则ID
    _fc_drag_tag: string;
    //拖拽模板规则ID
    _fc_template?: string;
    //生成组件名称
    type: string;
    //字段 ID
    field?: string;
    //编号
    name?: string;
    //字段名称
    title?: string;
    //提示信息
    info?: string;
    //组件的值
    value?: any;
    //组件的配置
    props: Object;
    //组件样式
    style: string | Object;
    //组件class
    class: string | Array;
    //组件事件
    on?: { [key: string]: Function | Function[] };
    //插槽名
    slot?: string;
    //组件的key
    key?: string;
    //是否必填
    $required: boolean | string;
    //组件的选择项
    options?: Array;
    //选择项对应的组件prop名称
    optionsTo?: string;
    //不使用formItem和wrap包裹
    native?: boolean;
    //是否隐藏组件(无dom)
    hidden?: boolean;
    //是否显示组件(有dom)
    display?: boolean;
    //是否进入阅读模式
    preview?: boolean;
    //自定义阅读模式回显
    readMode?: 'custom';
    //组件验证规则
    validate?: Object[];
    //子组件
    children?: Rule[];
    //联动数据
    control?: Array;
    //FormItem配置
    wrap?: Object;
    //逻辑条件/计算公式
    computed?: {
        [key: string]: string | Object;
    };
    //自定义属性
    effect?: {
        //远程数据
        fetch?: Object,
    };
    //其他扩展属性
    [key: string]: any;
}

说明

  • _fc_id: 组件规则的唯一标识符,用于在设计器中唯一定位每个组件。
  • props: 组件的属性配置,用于定义组件的行为和外观。
  • on: 组件的事件处理器,可以配置多个事件监听。
  • validate: 用于表单验证的规则列表。
  • children: 可以包含子组件,用于生成复杂的组件结构。

容器组件可拖入规则

AllowDragDenyDrag 用于定义容器组件的拖拽规则,分别控制哪些组件可以被拖拽到容器中,以及哪些组件不能被拖拽。

ts
//可拖入的组件列表
type AllowDrag = string[] | {
    //可拖入的菜单列表
    menu: string[];
    //可拖入的组件列表
    item: string[];
}
//不可拖入的组件列表
type DenyDrag = string[] | {
    //不可拖入的菜单列表
    menu: string[];
    //不可拖入的组件列表
    item: string[];
}

说明

  • AllowDrag: 定义容器中允许拖拽的组件或菜单。可以是一个组件 name 的数组,或者一个对象,其中 menuitem 分别指定允许的菜单和组件。
  • DenyDrag: 定义容器中不允许拖拽的组件或菜单。可以是一个组件 name 的数组,或者一个对象,其中 menuitem 分别指定禁止的菜单和组件。
  • 优先级: AllowDrag 配置优先级高于 DenyDrag

使用方法

在容器组件或者config中配置这些规则,以控制拖拽行为:

js
// 设置可拖拽规则
const allowDrag = {
    menu: ['main'],
    item: ['button', 'checkbox']
};
// 设置不可拖拽规则
const denyDrag = {
    menu: ['subform'],
    item: ['date-picker']
};

拖拽组件

描述规则结构

DragRule 用于定义设计器中的拖拽组件规则。每个拖拽组件都有一个唯一的 name 标识符,并通过 rule 方法生成组件规则。

ts
//多语言读取函数
type t = (name, ...args) => string;
//拖拽组件描述规则结构
interface DragRule {
    //组件id,不能重复
    name: string;
    //组件的名称
    label: string;
    //组件的图标
    icon: string;
    //插入的分类
    menu?: 'main' | 'aide' | 'layout' | 'template' | string;
    //如果是子表单组件,需要定义`value`的类型
    subForm?: 'object' | 'array';
    //可拖入的组件列表
    allowDrag?: AllowDrag;
    //不可拖入的组件列表
    denyDrag?: DenyDrag;
    //组件,不建议使用
    component?: Component;
    //渲染子组件的列表
    subRender: ({h, resolveComponent, subRule, rule}:{h:  typeof H<any>, resolveComponent: typeof ResolveComponent, subRule: Rule, rule:Rule})=>Array<{
        label: string;
        vnode: VNode
    }>;
    //配置组件条件选择方式
    condition: conditionComponentType | ((rule: Rule) => ({
        //组件类型
        type: conditionComponentType;
        //选择项
        options?: any[];
        //组件类型
        props?: Object;
    }));
    //模块组件配置参数
    container?: {
        //formData保存字段位置
        formDataField: string;
        //模块名称字段位置
        labelField: string;
    };
    //组件的生成规则
    rule(arg: { t: t }): Rule;
    //组件属性配置的规则
    props(rule: Rule, arg: { t: t, api: Api }): Rule[];
    //导出规则时通过这个方法转成最终规则
    parseRule?: (rule: Rule) => void;
    //导入规则时通过这个方法转成设计器中的渲染规则
    loadRule?: (rule: Rule) => void;
    //当props中的字段变化时触发
    watch?: {
        [key: string]: (arg: { value: any, rule: Rule, api: Api, field: string }) => void;
    };
    //是否有配套的子组件,例如Row和Col
    children?: string;
    //初始化时渲染几个子组件
    childrenLen?: number;
    //当前组件的操作容器是否显示在组件内部,为false时操作容器包裹当前组件
    inside?: true | boolean;
    //是否可以拖入其他组件到当前组件内部
    drag?: true | string | boolean;
    //是否显示拖拽按钮
    dragBtn?: false | boolean;
    //控制操作操作按钮是否显示,显示哪些
    handleBtn?: true | boolean | Array<'create' | 'copy' | 'addChild' | 'delete'>;
    //隐藏基础配置中的字段
    hiddenBaseField?: string[];
    //是否显示遮罩, 避免对组件操作. 建议有子组件时为true,其他为false
    mask?: false | boolean;
    //是否只能拖入一个
    only?: boolean;
    //是否生成name
    aide?: boolean;
    //是否支持样式配置
    style?: boolean;
    //当前组件支持的事件
    event?: string[];
    //当前组件`value`的数据类型
    validate?: string[] | boolean;
}

说明

  • rule方法: 生成组件的规则,返回一个 Rule 对象。
  • props方法: 用于定义组件的属性配置表单。
  • watch: 监听组件属性变化,并作出相应处理。
  • children: 用于支持具有子组件的组件,例如 RowCol

使用方法

定义好 DragRule 后,通过 designer.addComponent 方法导入组件规则。例如:

js
designer.addComponent(dragRule);

你也可以批量导入多个规则:

js
designer.addComponent([dragRule1, dragRule2, dragRule3]);

拖拽模板

描述规则结构DragTemplateRule 用于定义拖拽模板的规则结构。这些模板会显示在设计器左侧的模板区域,并可以拖拽到表单中使用。

ts
//拖拽模板描述规则结构
interface DragTemplateRule {
    //固定
    menu: 'template';
    //模板的id,不能重复
    name: string;
    //模板的名称
    label: string;
    //是否只能拖入一个
    only?: boolean;
    //是否自动替换规则中的字段名,表单中可能存在多个时建议为true,只支持自动生成的字段ID!
    autoField?: false | boolean;
    //模板的渲染规则,或者json规则,或者通过函数返回json规则
    template: Rule[] | string | ((arg: { t: t }) => string);
}

说明

  • template: 模板的渲染规则,支持多种格式,包括 JSON、字符串或函数返回的规则。
  • autoField: 自动生成字段 ID,当表单中可能存在多个相同模板时建议设置为 true。
  • only: 是否只能拖入一个。

使用方法

与拖拽组件类似,通过 designer.addComponent 方法导入模板规则:

js
designer.addComponent(dragTemplateRule);

设计器左侧菜单列表

ts
//拖拽组件
interface MenuItem {
    //拖拽组件名
    label: string;
    //拖拽组件id
    name: string;
    //拖拽组件图标
    icon: string;
}
//菜单
interface Menu {
    //菜单名
    title: string;
    //菜单id
    name: string;
    //拖拽组件列表
    list: MenuItem[];
}
type MenuList = Menu[];

说明 内置的菜单id分别是templatemainsubformaidelayout5个

  • template 模板组件
  • main 基础组件
  • subform 子表单组件
  • aide 辅助组件
  • layout 布局组件

设计器配置

设计器的props.config的配置

props.config 用于配置设计器的各类行为和界面元素。通过这些配置项,你可以对设计器进行定制化调整,以便更好地满足项目需求。以下是该配置的详细数据结构及其使用说明。

ts
//定义函数返回规则或者通过rule字段返回规则
type extendRule = ((arg: { t: t }) => Rule[]) | {
    //生成规则
    rule: (arg: { t: t }) => Rule[];
    //追加
    append?: boolean;
    //前置
    prepend?: boolean;
};
//field选择项
type FieldItem = {
    value?: string;
    label: string;
    //修改当前规则的必填,禁用和说明
    update?: {
        required?: Boolean;
        disabled?: Boolean;
        info?: string;
        title?: string;
    };
    children?: FieldItem[];
}
//自定义变量
type VarItem = {
    id?: string;
    label: string;
    children?: VarItem[];
}
//设计器组件的props.config配置
export interface Config {
    //是否可以切换组件类型,或者可以相互切换的字段
    switchType?: false | Array<string[]>;
    //是否自动选中拖入的组件
    autoActive?: boolean;
    //是否生成vue2语法的模板组件
    useTemplate?: boolean;
    //定义表单配置默认值
    formOptions?: Object;
    //配置field是否可以编辑
    fieldReadonly?: boolean;
    //field选择项,支持多级
    fieldList?: FieldItem[];
    //子表单组件是否可以选择`fieldList`中的最后一级
    fieldLeafSelectable?: boolean;
    //控制子表单组件字段是否和子表单字段联动, 默认开启
    relationField?: boolean;
    //自定义变量列表
    varList?: VarItem[];
    //隐藏拖拽操作按钮
    hiddenDragMenu?: boolean;
    //隐藏拖拽按钮
    hiddenDragBtn?: boolean;
    //隐藏部分菜单
    hiddenMenu?: MenuName[];
    //隐藏部分组件
    hiddenItem?: string[];
    //可拖入的组件列表
    allowDrag?: {
        //拖拽规则name: 可拖入的规则
        [id: string]: AllowDrag;
    };
    //不可拖入的组件列表
    denyDrag?: {
        //拖拽规则name: 不可拖入的规则
        [id: string]: DenyDrag;
    };
    //隐藏组件的部分配置项
    hiddenItemConfig?: {
        default?: string[];
        //拖拽规则name: 隐藏的字段名
        [id: string]: string[];
    };
    //禁用组件的部分配置项
    disabledItemConfig?: {
        default?: string[];
        //拖拽规则name: 禁用的字段名
        [id: string]: string[];
    };
    //是否显示保存按钮
    showSaveBtn?: boolean;
    //是否显示右侧的配置界面
    showConfig?: boolean;
    //是否显示组件的基础配置表单
    showBaseForm?: boolean;
    //是否显示组件联动
    showControl?: boolean;
    //是否显示绑定变量
    showVariable?: boolean;
    //是否显示模块管理
    showPageManage?: boolean;
    //是否显示组件的高级配置表单
    showAdvancedForm?: boolean;
    //是否显示组件的属性配置表单
    showPropsForm?: boolean;
    //是否显示组件的样式配置表单
    showStyleForm?: boolean;
    //是否显示组件的事件配置表单
    showEventForm?: boolean;
    //是否显示组件的验证配置表单
    showValidateForm?: boolean;
    //是否显示表单配置
    showFormConfig?: boolean;
    //是否显示左侧的模板列表
    showTemplate?: boolean;
    //是否显示多端适配选项
    showDevice?: boolean;
    //是否显示录入按钮
    showInputData?: boolean;
    //定义渲染规则所需的formData
    appendConfigData: string[] | ((rule: Rule) => Object);
    //基础配置的渲染规则,可以覆盖默认规则.append为true时追加到默认规则后面
    baseRule?: extendRule;
    //验证配置的渲染规则,可以覆盖默认规则.append为true时追加到默认规则后面
    validateRule?: extendRule;
    //表单的渲染规则,可以覆盖默认规则.append为true时追加到默认规则后面
    formRule?: extendRule;
    //组件配置的渲染规则,可以覆盖默认规则.append为true时追加到默认规则后面
    componentRule?: {
        default: (rule: Rule, arg: { t: t }) => Rule[] | {
            rule: (rule: Rule, arg: { t: t }) => Rule[];
            append?: boolean;
            prepend?: boolean;
        };
        //id组件拖拽组件规则的id,rule为当前组件的生成规则
        [id: string]: (rule: Rule, arg: { t: t }) => Rule[] | {
            rule: (rule: Rule, arg: { t: t }) => Rule[];
            append?: boolean;
            prepend?: boolean;
        };
    };
}

使用方法

通过 props.config 设置设计器的行为。例如:

vue
<fc-designer :config="designerConfig" />

其中 designerConfig 是基于上文所述结构的配置对象。

js
export default {
    data() {
        return {
            designerConfig: {
                formOptions: {},
                fieldReadonly: false,
                hiddenMenu: ['layout'],
                showConfig: true,
                // 其他配置项...
            }
        };
    }
}

通过合理配置这些选项,你可以根据项目需求定制化设计器的行为和展示内容。

全局数据源

全局数据源用于提供表单中可能需要的各种数据。数据源可以是静态数据(如预定义的数据列表)或动态数据(通过远程 API 获取的数据)。

ts
interface StaticDataItem {
    //数据名称
    label: string;
    //数据类型
    type: 'static';
    //数据
    result: any;
}


interface FetchDataItem {
    //数据名称
    label: string;
    //数据类型
    type: 'fetch'
    //请求链接
    action: string,
    //请求方式
    method: 'GET' | 'POST',
    //请求头部
    headers?: Object,
    //附带数据
    data?: Object,
    //远程数据解析
    parse?: string | ((res: any) => any),
    //远程异常处理
    onError?: string | ((e) => void),
}


export interface GlobalData {
    [id:string] : StaticDataItem | FetchDataItem;
}

使用说明

  • 使用 setGlobalData 方法导入预设的数据。
  • 也可以在表单配置中通过 options.globalData 来指定全局数据源。

全局事件

全局事件用于定义可以在表单中触发的事件及其处理方式。

ts
interface GlobalEvent {
    [id: string]: {
        //数据名称
        label: string;
        //是否可以删除
        deletable: boolean;
      	//回调事件
        handle: string | (($inject: Object) => void);
    }
}

使用说明

  • 使用 setGlobalEvent 方法导入预设的事件。
  • 也可以在表单配置中通过 options.globalEvent 来指定全局事件。

全局样式

全局样式用于定义可以在表单中应用的样式类。

ts
interface GlobalClass {
    [className: string]: {
        //数据名称
        label: string;
        //是否可以删除
        deletable: boolean;
      	//回调事件
        style: Obejct;
    }
}

使用说明

  • 使用 setGlobalClass 方法导入预设的样式。
  • 也可以在表单配置中通过 options.globalClass 来指定全局样式。

全局变量

全局变量用于定义表单中需要使用的变量及其计算逻辑。

ts
export interface GlobalVariable {
    [id: string]: {
        //数据名称
        label: string;
        //是否可以删除
        deletable: boolean;
        //回调事件
        handle: string | ((get: Function, api: Api) => any);
    }
}

使用说明

  • 使用 setGlobalVariable 方法导入预设的变量。
  • 也可以在表单配置中通过 options.globalVariable 来指定全局变量。

扩展操作

扩展操作用于定义在设计器中可用的额外操作按钮及其处理函数。

typescript
type Handle = Array<{
    //按钮名称
    label: string;
    //回调函数
    callback: Function;
}>

可以通过config.handle扩展设计器的操作

层级结构

层级结构用于描述表单中组件的层次关系和属性。

typescript
type TreeData = Array<{
  	//唯一值
    _fc_uni: string;
  	//组件类型
    type: string;
  	//字段ID
    field?: string;
  	//字段名称
    title?: string;
  	//插槽
    slot?: string;
  	//属性
    props: Object;
  	//子级
    children?: TreeData;
}>

可以通过getTreegetFormTree方法获取描述规则

计算函数

计算函数用于定义自定义的计算逻辑,可以用于表单中的各种计算操作。

typescript
type Formula = {
    //菜单
    menu: 'math' | 'string' | 'date' | 'collection' | 'condition';
    //计算函数名
    name: string;
    //计算函数说明
    info: string;
    //计算函数使用示例
    example: string;
    //计算函数
    handle: Function;
};

可以通过FcDesigner.setFormula方法扩展计算规则