TS数据结构
本文档详细介绍了 fcDesigner
中各个核心数据结构的 TypeScript
定义。这些数据结构定义了如何生成组件、拖拽组件、配置设计器等。通过理解这些数据结构,你可以自定义和扩展设计器的功能,以满足不同的业务需求。
组件生成规则
组件的 JSON 数据结构
Rule
是描述组件生成规则的核心数据结构。每个组件都有一个唯一的 _fc_id 标识符和其他属性,用于定义组件的类型、样式、事件、验证规则等。
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: 可以包含子组件,用于生成复杂的组件结构。
容器组件可拖入规则
AllowDrag
和 DenyDrag
用于定义容器组件的拖拽规则,分别控制哪些组件可以被拖拽到容器中,以及哪些组件不能被拖拽。
//可拖入的组件列表
type AllowDrag = string[] | {
//可拖入的菜单列表
menu: string[];
//可拖入的组件列表
item: string[];
}
//不可拖入的组件列表
type DenyDrag = string[] | {
//不可拖入的菜单列表
menu: string[];
//不可拖入的组件列表
item: string[];
}
说明
- AllowDrag: 定义容器中允许拖拽的组件或菜单。可以是一个组件
name
的数组,或者一个对象,其中menu
和item
分别指定允许的菜单和组件。 - DenyDrag: 定义容器中不允许拖拽的组件或菜单。可以是一个组件
name
的数组,或者一个对象,其中menu
和item
分别指定禁止的菜单和组件。 - 优先级:
AllowDrag
配置优先级高于DenyDrag
。
使用方法
在容器组件或者config
中配置这些规则,以控制拖拽行为:
// 设置可拖拽规则
const allowDrag = {
menu: ['main'],
item: ['button', 'checkbox']
};
// 设置不可拖拽规则
const denyDrag = {
menu: ['subform'],
item: ['date-picker']
};
拖拽组件
描述规则结构
DragRule
用于定义设计器中的拖拽组件规则。每个拖拽组件都有一个唯一的 name
标识符,并通过 rule
方法生成组件规则。
//多语言读取函数
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: 用于支持具有子组件的组件,例如
Row
和Col
。
使用方法
定义好 DragRule 后,通过 designer.addComponent 方法导入组件规则。例如:
designer.addComponent(dragRule);
你也可以批量导入多个规则:
designer.addComponent([dragRule1, dragRule2, dragRule3]);
拖拽模板
描述规则结构DragTemplateRule
用于定义拖拽模板的规则结构。这些模板会显示在设计器左侧的模板区域,并可以拖拽到表单中使用。
//拖拽模板描述规则结构
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 方法导入模板规则:
designer.addComponent(dragTemplateRule);
设计器左侧菜单列表
//拖拽组件
interface MenuItem {
//拖拽组件名
label: string;
//拖拽组件id
name: string;
//拖拽组件图标
icon: string;
}
//菜单
interface Menu {
//菜单名
title: string;
//菜单id
name: string;
//拖拽组件列表
list: MenuItem[];
}
type MenuList = Menu[];
说明 内置的菜单id分别是template
,main
,subform
,aide
,layout
5个
- template 模板组件
- main 基础组件
- subform 子表单组件
- aide 辅助组件
- layout 布局组件
设计器配置
设计器的props.config
的配置
props.config
用于配置设计器的各类行为和界面元素。通过这些配置项,你可以对设计器进行定制化调整,以便更好地满足项目需求。以下是该配置的详细数据结构及其使用说明。
//定义函数返回规则或者通过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 设置设计器的行为。例如:
<fc-designer :config="designerConfig" />
其中 designerConfig 是基于上文所述结构的配置对象。
export default {
data() {
return {
designerConfig: {
formOptions: {},
fieldReadonly: false,
hiddenMenu: ['layout'],
showConfig: true,
// 其他配置项...
}
};
}
}
通过合理配置这些选项,你可以根据项目需求定制化设计器的行为和展示内容。
全局数据源
全局数据源用于提供表单中可能需要的各种数据。数据源可以是静态数据(如预定义的数据列表)或动态数据(通过远程 API 获取的数据)。
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 来指定全局数据源。
全局事件
全局事件用于定义可以在表单中触发的事件及其处理方式。
interface GlobalEvent {
[id: string]: {
//数据名称
label: string;
//是否可以删除
deletable: boolean;
//回调事件
handle: string | (($inject: Object) => void);
}
}
使用说明
- 使用 setGlobalEvent 方法导入预设的事件。
- 也可以在表单配置中通过 options.globalEvent 来指定全局事件。
全局样式
全局样式用于定义可以在表单中应用的样式类。
interface GlobalClass {
[className: string]: {
//数据名称
label: string;
//是否可以删除
deletable: boolean;
//回调事件
style: Obejct;
}
}
使用说明
- 使用
setGlobalClass
方法导入预设的样式。 - 也可以在表单配置中通过
options.globalClass
来指定全局样式。
全局变量
全局变量用于定义表单中需要使用的变量及其计算逻辑。
export interface GlobalVariable {
[id: string]: {
//数据名称
label: string;
//是否可以删除
deletable: boolean;
//回调事件
handle: string | ((get: Function, api: Api) => any);
}
}
使用说明
- 使用 setGlobalVariable 方法导入预设的变量。
- 也可以在表单配置中通过 options.globalVariable 来指定全局变量。
扩展操作
扩展操作用于定义在设计器中可用的额外操作按钮及其处理函数。
type Handle = Array<{
//按钮名称
label: string;
//回调函数
callback: Function;
}>
可以通过config.handle
扩展设计器的操作
层级结构
层级结构用于描述表单中组件的层次关系和属性。
type TreeData = Array<{
//唯一值
_fc_uni: string;
//组件类型
type: string;
//字段ID
field?: string;
//字段名称
title?: string;
//插槽
slot?: string;
//属性
props: Object;
//子级
children?: TreeData;
}>
可以通过getTree
和getFormTree
方法获取描述规则
计算函数
计算函数用于定义自定义的计算逻辑,可以用于表单中的各种计算操作。
type Formula = {
//菜单
menu: 'math' | 'string' | 'date' | 'collection' | 'condition';
//计算函数名
name: string;
//计算函数说明
info: string;
//计算函数使用示例
example: string;
//计算函数
handle: Function;
};
可以通过FcDesigner.setFormula
方法扩展计算规则