Skip to content

FormQuery 查询表单 ​

简介 ​

FormQuery 是预设了栅格布局的 Form 组件,拥有相同的接口,并添加了折叠功能,通常和表格组件一起使用。

字段有两种写法,可以混用:

  • 插槽:手写 <co-form-item v-model="...">,适合结构自由、联动复杂的场景;
  • 声明式:传 schemes 数组,每项就是一份 FormItem 属性,值统一落到 model 上。

不传 model 时组件会自己维护一个模型,用 getFieldsValue() / setFieldsValue() 读写—— 查询栏、弹窗里的筛选条都可以直接用它,不需要额外的容器组件。

代码演示 ​

基础演示 ​

声明式字段 ​

schemes 里的每一项都是一份 FormItem 的属性,modelValue 即该字段初值。 需要完全自定义控件时,用 render({ model }) 返回自己的内容。

不能给 FormItem 用的属性(比如 render)会被剔除,slots 会原样传给 FormItem。 输入框里按 Enter 就会提交(submit-on-enter 默认开启,普通表单不需要时传 false)。

拆分成两个字段 ​

日期范围控件绑定的是数组,接口要的往往是两个独立参数。给字段加 split,getFieldsValue() 就会把它拆成两个键:

ts
{
  prop: 'createdAt',
  label: '创建时间',
  fieldType: 'daterange',
  split: ['startCreatedAt', 'endCreatedAt'],
}
  • 模型里仍然只存源字段的数组(model.createdAt):控件、校验、重置都走 el-form 原本那一套,type: 'array' 之类的规则照旧可用;
  • 只有 getFieldsValue() 的输出是拆开的两个键,空着的一端不输出;
  • 反向也通:setFieldsValue() / reset-values 里给这两个键会合成回源字段,只给一端时另一端沿用模型里现有的值;
  • 插槽写法同样支持,把 split 写在 co-form-item 上即可。

请求参数一律取 getFieldsValue(),别直接拿 model —— 它存的是控件值,不是接口形状。

自定义按钮 ​

submit / reset 插槽只替换对应的那个按钮,折叠按钮照旧;要整块换掉按钮区就用 button 插槽,它的优先级更高。

两个插槽都拿到操作函数和状态:submit 插槽给 submit、submitting(按钮自己决定 loading 怎么画),reset 插槽给 reset(已经带上了 reset-values 的处理)。

分组 ​

字段多的时候按语义分组:groups 声明组的名称与顺序,字段上用 group 指定所属组,组名默认独占一行(右侧一条细线)。声明式字段和手写 co-form-item 都能归组。

  • 段内保持书写顺序,没标记或组名没声明的字段排在最后一段,不带组头;
  • 栅格和行内(grid="false")都生效:栅格里每组是一个整行区块,行内里每组是一段「组名 + 行内字段」;
  • 和折叠一起用时,一整组字段都被收起,组名也跟着隐藏,不会留一截悬空。

group-layout="left" 把组名挪到左侧一列(96px),省掉每组的标题行;容器宽度不足 576px(手机尺寸)时自动退回顶部,不用自己判断。左侧这一列会挤占字段宽度,通常要配合少排一列(比如 col-props 从三列改两列),示例里的切换就是这么做的。

行内模式下 left 就是「每组一行」:组名一列,字段在右侧接着排、放不下才换行。

用了 groups 时,「提交 / 重置」排在最后一组里、紧跟在最后的字段之后,不再单独占一行:栅格里补到本行空出来的格子,行内里挤在字段同一行的右端;一整组字段都被折叠时才会退回独立一行。

自定义组标题 ​

label 只够写文字。要塞图标、数量这类内容,用 group-title 插槽统一改,或者用 groups[].render 只改某一组:插槽优先,其次 render,最后才是 label,三者都没有就只分段、不留标题。

插槽与 render 都拿到 group(分组定义)和 index(在 groups 里的序号),返回的内容会放进组名所在的横条里,两侧细线照旧。

组名左置时,标题列的宽度用 group-title-width 统一设置(默认 96px),标题内容换成什么都不会改变列宽。下面的示例把标题换成一枚 el-tag,并把列宽放宽到 120px:

行内筛选条 ​

关掉栅格(:grid="false")并开启 inline,就是表格头部、下拉弹层里那种一行排开的筛选条。

这种排布没有列宽托底,控件会被压到输入框的固有宽度(状态 这种窄控件甚至会被挤成一条), 所以非栅格 + inline 时 min-width 默认取 200:空间不够就整项换行,而不是继续挤。 需要别的下限就显式传 min-width;显式传了 width 则不再兜这个默认值。

浏览器宽度 ≤ 768px 时会自动退出行内(inline 失效),表单项变成块级、撑满容器,不会再挤成一列窄控件。

非栅格没有「列」的概念,「显示一行」无从计算,所以收起数量只能由 min-fields 显式给出: 传正数就按该数量折叠,并出现展开/收起按钮;默认 -1 时不隐藏任何字段、也没有按钮。

默认展开 ​

使用 collapsed 属性设置折叠状态,也可以用 v-model:collapsed 双向绑定。

最小显示表单项数 ​

默认在折叠状态下会显示一行的表单控件,通过 min-fields 属性可以设置折叠时显示的固定数量的表单控件。

非栅格模式(:grid="false")没有「行」的概念,只有传正数时才会折叠。

隐藏折叠按钮 ​

设置 :min-fields="0" 可以隐藏折叠按钮。

垂直排布 ​

设置 label-position="top" 实现垂直排布,可以使表单控件有更多的展示空间。

校验失败自动展开 ​

收起状态下被隐藏的字段仍然参与校验(FormItem 只是被设成 display: none), 出错却完全看不见 —— 用户会以为「点了查询没反应」。所以校验失败时表单会自动展开。

API ​

FormQueryProps ​

继承 FormProps,并有以下额外属性或默认值。

属性描述类型默认值
grid是否开启栅格化模式booleantrue
col-props栅格化模式下设置所有 field 共同的 Col 的属性ColProps{ xs: 24, sm: 12, md: 8, lg: 6, xl: 6 }
min-width控件区的最小宽度,非栅格 + inline 时默认 200FormItemWidth-
min-fields自定义折叠状态下默认显示的表单控件数量,小于 0,则显示一行控件(非栅格模式下不算「行」,不折叠); 等于 0,则显示所有控件;数量大于等于控件数量则隐藏展开按钮number-1
collapsed是否折叠超出的表单项booleantrue
reset-values点击重置按钮时,可以用指定表单值来重置() => Record<string, any>-
switch-to-invalid校验失败时自动展开,把出错的字段露出来booleantrue
schemes声明式字段;与插槽里的 co-form-item 等价,各项 modelValue 即初值FormQueryScheme[][]
submit-on-enter输入框里按 Enter 直接提交booleantrue
groups按组排布字段,组头独占一行;提交按钮排在最后一组里FormQueryGroup[][]
group-layout组名位置:top 独占一行,left 在左侧占一列(<576px 自动回落 top)top | lefttop
group-title-width组名左置时标题列的宽度,统一作用于所有分组;top 布局下无效string | number96px

FormQueryScheme ​

ts
type FormQueryScheme = FormItemProps<FieldType> & {
  render?: (params: { model: Record<string, any> }) => VNodeChild;
  slots?: Record<string, unknown>;
};

其中 split 用于把一个字段拆成两个输出键,见拆分成两个字段。

FormQueryGroup ​

属性描述类型
name与字段上的 group 对应string
label组标题,不传则只分段、不留标题string
render自定义组标题内容,优先于 label;插槽 group-title 又优先于它(params: FormQueryGroupTitleParams) => VNodeChild
ts
type FormQueryGroupTitleParams = {
  group: FormQueryGroup;
  index: number;
};

FormQuerySlots ​

继承 FormSlots(含 button / submit / reset),并有以下额外插槽。

插槽描述参数
group-title自定义组标题,优先于 groups[].render 与 label{ group: FormQueryGroup; index: number }

FormQueryEmits ​

继承 FormEmits,并有以下额外事件。

事件描述类型
update:collapsed折叠状态改变时触发(collapsed: boolean) => void

FormQueryExpose ​

继承 FormExpose,并有以下额外方法。

方法描述类型
getFieldsValue模型快照(深拷贝),可直接当请求参数() => Record<string, any>
setFieldsValue批量写模型(values: Record<PropertyKey, any>) => void
getModel原始模型(响应式对象),改它不会触发查询,需要配合 submit()() => Record<string, any>
reset传回调时同 FormExpose.reset;传对象时先重置、再把对象写回模型(valuesOrCallback?: Record<PropertyKey, any> | (() => void)) => void

基于 MIT 许可发布