HForm
这是一个对NaiveUI表单组件Form,进行JSON配置化处理,简化其复杂的实现过程,主要包含两种模式:FORM(表单录入),FILTER(筛选器)两种模式
筛选器
自定义搜索按钮
可以通过插槽slot(search)完全自定义搜索区,或通过props(searchBtn)属性更改按钮的文案
<template>
<HForm type="FILTER" :rules="filterRules" @search="search" @reset="reset">
<template #search>
<div>
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
</div>
</template>
</HForm>
</template><template>
<HForm
type="FILTER"
:rules="filterRules"
@search="search"
@reset="reset"
:search-btn="{
search: { text: '查询', loading: searchLoading },
reset: { text: '更多' },
}"/>
</template>表单录入
动态数据
需要对表单设置为响应式数据,使用reactive或ref修饰,然后使用onLoad钩子函数(只加载一次),进行数据的远程加载,最后通过HFormApi的setOptionsAPI,进行表单数据的绑定操作
const HFormRules = reactive<HFormRule[]>([
{
field: 'grade',
compType: 'Select',
label: '年级',
required: true,
onLoad(fApi:HFormApi){
setTimeout(()=>{
fApi.setOptions('grade',[
{ label: '1年级', value: '1' },
{ label: '2年级', value: '2' },
])
},1000)
}
},
])详细示例如下
表单项联动操作
表单项之间若存在依赖关系,可以通过暴漏的HFormApi对象,进行表单项间的动态联动操作
根据年龄联动年级
当年龄小于18岁时,年级为1年级;大于等于18岁为2年级
{
field: 'age',
compType: 'InputNumber',
label: '年龄',
required: true,
props(formApi: HFormApi) {
return {
onChange(value: number) {
//设置年级可选数据
if (value < 16) {
formApi.setOptions('grade', [{ label: '1年级', value: '1' },])
} else {
formApi.setOptions('grade', [ { label: '2年级', value: '3' },])
}
},
}
},
}示例效果如下:
自定义表单项
在某些场景下,有些组件不满足需求,可以通过自定表单项的方式进行实现。
<template>
<HForm type="FORM" card :rules="HFormRules" @confirm="commit" >
<template #grade>
<!-- TODO 自定义表单项 -->
</template>
</HForm>
</template>
<script lang="ts" setup>
import { HFormRule, HForm, HFormApi} from 'hyb-naive'
import { reactive,ref } from 'vue'
const HFormRules = reactive<HFormRule[]>([
{
field: 'grade',
compType: 'Slot',
label: '年级',
span:24,
required: true,
},
])
const formData = ref({})
function commit(data: object) {
console.log('formData=', data)
formData.value=data
}
</script>示例:自定义性格标签
通过自定义项和validator校验器,实现表单的数据验证,validator具体使用,请查看naive-ui/lib/form/src/interface下的FormItemRuleValidator,自定义组件中对外暴露出了HFormApi中的功能和对象,这里使用了#character={formData} 通过标签的数据变化时间,绑定到表单数据中@update:value="($event)=>formData.character=$event"
具体效果和完整代码如下:
组件示例
HFormApi
前面多次提到了HFormApi,很多的一些操作都是通过他
具体Api内容如下
| 字段 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| formData | 表单数据 | - | {} |
| setFormData | 设置整个表单数据 | (formData: object) => void | - |
| setValue | 设置表单项数据, 并返回表单值 | (field: string, value: any) => Promise<any> | - |
| setValues | 设置多个表单项数据, 并返回表单值 | (values: object) => Promise<any> | - |
| setRule | 设置表单规则 | (field: string, rule: HFormRule) => HFormRule | - |
| getRule | 获取表单规则 | (field: string) => HFormRule | undefined | - |
| mergeRule | 合并表单规则 | (field: string, rule: HFormRule) => HFormRule | - |
| setOptions | 设置表单数据选择项 | (field: string, options: Array<{ label?: string; value?: any; [key: string]: any }>) => Promise<any> | - |
| validate | 校验表单 | () => Promise<object> | - |
| search | 触发搜索 | (formData?: object) => void | - |
| reset | 重置表单 | () => void | - |
| rules | 表单规则 | - | - |
| value | 当前表单项的值(可选) | - | - |
| rule | 表单规则(可选) | - | - |
补充说明
- formData:用于存储表单的数据,默认是一个空对象。
- setFormData:用于设置整个表单的数据,参数为一个对象。
- setValue 和 setValues:分别用于设置单个表单项和多个表单项的数据,返回更新后的表单数据。
- setRule 和 getRule:用于设置和获取表单规则,参数为字段名和规则对象。
- mergeRule:与
setRule不同,它只更新指定字段的规则,而不是替换整个规则。 - setOptions:用于设置表单项的选项,参数为字段名和选项数组,返回更新后的选项列表。
- validate:用于校验表单,返回校验结果。
- search:触发搜索操作,可以传递表单数据作为参数。
- reset:重置表单,清除所有表单数据。
- rules:定义表单的规则集合。
- value 和 rule:可选字段,用于存储表单数据和规则。
只有在表单项钩子函数中才有值
怎样获取HFormApi?
- 通过组件实例获取HFormApi
<template>
<HForm type="FORM" card :rules="HFormRules" @confirm="commit" :cols="2" ref="formRef"/>
</template>
<script lang="ts" setup>
import { HFormRule, HForm, HFormApi} from 'hyb-naive'
import { reactive,ref } from 'vue'
//通过HForm实例获取
const formRef= ref<InstanceType<typeof HForm>>()
//然后通过
formRef.value?.setFormData({
age:18,
sex:1
})
</script>注意
formRef 可以直接调用上述的Api函数和对象,HForm组件defineExpose对外暴漏了这些Api,方便开发者使用。而这个时候获取不到value和rule的值, 就是上述所说的只有在表单项钩子函数中才有值,因为这里获取的是整个表单组件的实例,而这两个值都是和表单项绑定在一起的。
- 通过表单项的钩子函数获取
HFormApi。如props中获取HFormApi, 在表单配置中,props可以是一个object也可以是一个Function,如果不需要通过FormApi对表单进行操作,就可以直接定义成一个对象,否则就只能通过函数来获取。
{
field: 'age',
compType: 'InputNumber',
label: '年龄',
fullWidth: true,
required: true,
validateType: 'number',
props(formApi: HFormApi) {
return {
onChange(value: number) {
//设置班级数据
if (value < 18) {
formApi.setOptions('grade', [
{ label: '1年级', value: '1' },
])
} else {
formApi.setOptions('grade', [
{ label: '2年级', value: '4' },
])
}
},
}
},
},props都有哪些配置信息,如何配置?
这里解释一下,props是根据你配置组件的类型(compType),具体有哪些参数,参考naive-ui中对应的组件的props进行一一对应; 注意:这里是可以取到HFormApi中的value(当前表单项的值)和rule(当前表单项的规则)字段的值
HFormApi操作无效果?
注意,注意,注意
要想使用HFormApi进行对表单操作,最重要的前提是,必须对表单数据设置为响应式数据,否则没有效果
//错误示例
const formRules = [{
field: 'age',
compType: 'InputNumber',
label: '年龄',
fullWidth: true,
required: true,
validateType: 'number',
props(formApi: HFormApi) {
return {
onChange(value: number) {
//设置班级数据
if (value < 18) {
formApi.setOptions('grade', [
{ label: '1年级', value: '1' },
])
} else {
formApi.setOptions('grade', [
{ label: '2年级', value: '4' },
])
}
},
}
},
}]
// 正确的写法
const formRules = reactive([{
field: 'age',
compType: 'InputNumber',
label: '年龄',
fullWidth: true,
required: true,
validateType: 'number',
props(formApi: HFormApi) {
return {
onChange(value: number) {
//设置班级数据
if (value < 18) {
formApi.setOptions('grade', [
{ label: '1年级', value: '1' },
])
} else {
formApi.setOptions('grade', [
{ label: '2年级', value: '4' },
])
}
},
}
},
},
// ...others
])HForm
Props
| 字段 | 说明 | 类型 | 默认值 | 必填 |
|---|---|---|---|---|
| cols | 表单列数 | number | type为FILTER时默认为4,FORM默认为1 | 否 |
| labelWidth | 标签宽度 | number | 80 | 否 |
| labelPlacement | 标签位置,可选值为 left 或 top | 'left' | 'top' | left | 否 |
| size | 表单大小,可选值为 small、medium 或 large | 'small' | 'medium' | 'large' | small | 否 |
| labelAlign | 标签对齐方式,可选值为 left、right 或 center | 'left' | 'right' | 'center' | right | 否 |
| disabled | 是否禁用表单 | boolean | false | 否 |
| title | 表单标题 | string | 空 | 否 |
| rules | 表单规则数组 | HFormRule[] | - | 是 |
| formData | 表单数据 | Record<string, any> | {} | 否 |
| filterNullValue | 点击搜索时是否过滤空值提交,且仅在筛选模式(FILTER)时有效 | boolean | true | 否 |
| type | 表单类型,可选值为 FORM 或 FILTER | 'FORM' | 'FILTER' | FORM | 是 |
| card | 是否启用卡片模式 | boolean | false | 否 |
| immediateUpdate | 是否立即回调 formData 数据变化 | boolean | false | 否 |
| borderRadius | 表单边框圆角 | number | 7 | 否 |
| searchFirstRow | 是否将搜索和重置按钮显示在第一行的末尾 | boolean | true | 否 |
| searchBtn | 搜索按钮配置 | { searchSpan?: number; search?: ButtonProps | boolean; reset?: ButtonProps | boolean } | - | 否 |
| showFormBtn | 是否显示表单的取消和确认按钮, FORM模式有效 | boolean | true | 否 |
| formBtn | 表单的取消和确认按钮配置 | { cancel?: ButtonProps; confirm?: ButtonProps } | - | 否 |
| initSearch | 初始化搜索时是否回调 search 事件 | boolean | true | 否 |
ButtonProps
| 字段 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| text | 按钮文本 | string | - |
| show | 是否显示按钮 | boolean | true |
| disabled | 是否禁用按钮 | boolean | false |
| loading | 是否显示加载状态 | boolean | false |
| interceptEvent | 是否拦截事件, 目前只有重置事件做了拦截, 其他按钮未做处理;后续优化处理 | boolean | false |
HFormRule 表单配置
属性
| 字段 | 说明 | 类型 | 默认值 | 必填 |
|---|---|---|---|---|
| field | 表单字段名 | string | - | 是 |
| label | 标签名称 | string | - | 是 |
| labelAlign | 标签对齐方式 | 'left' | 'center' | 'right' | right | 否 |
| required | 是否必填项 | boolean | ((fApi: HFormApi) => boolean) | false | 否 |
| compType | 组件类型 | HFormCompType | ((fApi: HFormApi) => HFormCompType) | - | 是 |
| trigger | 校验事件 | string | string[] | FORM模式且required为true时默认[blur, change, input] | 否 |
| message | 验证错误提示消息 | string | FORM模式且required为true时默认${label}不能为空 | 否 |
| span | 24栅格暂用的空间大小 | number | (() => number) | FORM默认24,FILTER默认6 | 否 |
| defaultValue | 默认值 | any | - | 否 |
| labelWidth | 标签的宽度 | number | string | 默认取HForm的labelWidth | 否 |
| validateType | 数据类型校验 | HValidateType | string | 否 |
| validator | 表单校验器,自定义校验规则 | FormRuleValidator | - | 否 |
| fullWidth | 是否填充整个宽度 | boolean | false | 否 |
| ignoreCommit | FORM模式下是否忽略表单提交 | boolean | false | 否 |
| restValue | 是否重置数据,某些情况下有些数据不需要重置 | boolean | false | 否 |
| show | 是否显示 | boolean | ((fApi: HFormApi) => boolean) | true | 否 |
| props | 组件参数 | object | ((fApi: HFormApi) => object) | - | 否 |
| options | 当组件类型为 RadioGroup、RadioButtonGroup、Select 的选项内容 | Array<{ label?: string; value?: any; [key: string]: any }> | ((fApi: HFormApi) => Array<{ label?: string; value?: any; [key: string]: any }>) | - | 否 |
| onLoad | 组件加载钩子函数 | (fApi: HFormApi) => void | - | 否 |
| disabled | 是否禁用表单项 | boolean | ((fApi: HFormApi) => boolean) | false | 否 |
HFormCompType组件类型
| 组件名称 | 说明 |
|---|---|
| Input | 输入框 |
| InputNumber | 数字输入框 |
| Select | 下拉选择框 |
| TreeSelect | 树形选择框 |
| RadioButtonGroup | 单选按钮组 |
| RadioGroup | 单选按钮组 |
| Radio | 单选按钮 |
| Checkbox | 复选框 |
| CheckboxGroup | 复选框组 |
| AutoComplete | 自动补全输入框 |
| Cascader | 级联选择器 |
| DatePicker | 日期选择器 |
| Switch | 开关 |
| Upload | 文件上传 目前还有问题暂不支持 |
| Slider | 滑块 |
| Rate | 评分组件 |
| Tree | 树形组件 |
| Transfer | 穿梭框 |
| Slot | 插槽 |
| TimePicker | 时间选择器 |
Events
| 事件名称 | 说明 | 参数 |
|---|---|---|
| dataChange | 表单数据变化时触发 | formData: Record<string, any> |
| search | 搜索时触发 | formData: Record<string, any> |
| reset | 重置表单时触发 | formData: Record<string, any> |
| cancel | FORM模式下使用,取消操作时触发 | 无 |
| confirm | FORM模式下使用,确认操作时触发 | formData: Record<string, any> |
Slot
| 名称 | 说明 |
|---|---|
| search | 搜索和重置按钮的插槽控制 |
动态插槽,根据表单配置的项进行动态化配置[field] | 当表单项的compType为Slot时,会触发该插槽, 以满足特殊场景的组件需求,定制化、特殊化 |
