FitsFormCreate 表单
# FitsFormCreate 表单
# 普通表单
普通表单展示。数据类型为 FitsFormCreateModel
。使用该表单组件必须传入 rule
:生成表单的规则。本例为了展示提交表单的效果,还传入了 option.onSubmit
,以提示框的形式展现提交后获得的表单数据。
<template>
<fits-form-create :form="simpleForm" />
</template>
<script setup lang="ts">
import { Search } from '@element-plus/icons-vue'
import { FitsFormCreate } from '@/fits-components';
import { FitsFormCreateModel, FitsCheckboxAllModel } from '@/fits-components/type';
import FitsCheckboxAll from '@/fits-components/Form/Checkbox/FitsCheckboxAll.vue';
import FitsFormTitle from '@/fits-components/Form/Other/FormTitle.vue';
const simpleForm = reactive(
new FitsFormCreateModel({
rule: [
{
type: 'title',
component: markRaw(FitsFormTitle),
field: "divider",
value: '输入控件',
style: "background:#F2F2F2;color:#303133;line-height:32px;padding-left:16px;"
},
{
type: "input",
title: "输入框",
field: "input",
props: {
prefixIcon: markRaw(Search)
},
},
{
type: "input",
title: "多行文本",
field: "textarea",
props: {
type: "textarea",
placeholder: "请输入商品名称",
rows: 5,
autosize: { minRows: 2, maxRows: 5 }
}
},
{
type: 'title',
component: markRaw(FitsFormTitle),
field: "divider",
value: '选择控件',
style: "background:#F2F2F2;color:#303133;line-height:32px;padding-left:16px;"
},
{
type: "select",
title: "下拉选择",
field: "select1",
props: {
clearable: true
},
options: [
{
value: "104",
label: "生态蔬菜",
disabled: false
},
{
value: "105",
label: "新鲜水果",
disabled: true
},
{
value: "106",
label: "蛋糕甜点",
disabled: false
},
],
},
{
type: "select",
title: "筛选、创建条目",
field: "select2",
props: {
filterable: true,
allowCreate: true,
multiple: true
},
options: [
{
value: "104",
label: "生态蔬菜",
disabled: false
},
{
value: "105",
label: "新鲜水果",
disabled: false
},
{
value: "106",
label: "蛋糕甜点",
disabled: false
}
]
},
{
type: "radio",
title: "单选",
field: "radio1",
options: [
{
value: "104",
label: "生态蔬菜",
disabled: false
},
{
value: "105",
label: "新鲜水果",
disabled: true
},
{
value: "106",
label: "蛋糕甜点",
disabled: false
},
{
value: "107",
label: "生态蔬菜",
disabled: false
},
{
value: "108",
label: "农产鸡蛋",
disabled: false
}
]
},
{
type: "radio",
title: "单选按钮组",
field: "radio2",
props: {
type: 'button'
},
options: [
{
value: "104",
label: "生态蔬菜",
disabled: false
},
{
value: "105",
label: "新鲜水果",
disabled: false
},
{
value: "106",
label: "蛋糕甜点",
disabled: false
},
]
},
{
type: 'title',
component: markRaw(FitsFormTitle),
field: "divider",
value: '开关控件',
style: "background:#F2F2F2;color:#303133;line-height:32px;padding-left:16px;"
},
{
type: "switch",
title: "开关",
field: "switch1",
col: {
span: 4
}
},
{
type: "switch",
title: "开关",
field: "switch2",
props: {
inactiveColor: '#000',
activeColor: 'pink',
size: "large",
inlinePrompt: true,
activeText: '开',
inactiveText: '关'
},
col: {
span: 4
},
on: {
change: (val: any) => {
console.log(val)
}
}
},
{
type: 'title',
component: markRaw(FitsFormTitle),
field: "divider",
value: '日期、时间控件',
style: "background:#F2F2F2;color:#303133;line-height:32px;padding-left:16px;"
},
{
type: "DatePicker",
title: "日期选择",
field: "DatePicker1",
},
{
type: "DatePicker",
title: "带快捷选项",
field: "DatePicker2",
props: {
shortcuts: [
{
text: '今日',
value: moment().format()
},
{
text: '昨日',
value: () => {
return moment().subtract(1, 'day').format()
},
},
{
text: '一周前',
value: () => {
return moment().subtract(7, 'day').format()
},
},
]
},
},
{
type: "DatePicker",
title: "日期范围",
field: "DatePicker3",
props: {
type: "daterange",
rangeSeparator: "至",
startPlaceholder: "开始日期",
endPlaceholder: "结束日期",
unlinkPanels: true
},
},
{
type: "DatePicker",
title: "月范围",
field: "DatePicker4",
props: {
type: "monthrange",
rangeSeparator: "至",
startPlaceholder: "开始月份",
endPlaceholder: "结束月份",
unlinkPanels: true
},
},
{
type: "DatePicker",
title: "日期时间选择",
field: "DatePicker4",
props: {
type: "datetimerange",
},
},
{
type: "TimePicker",
field: "time",
title: "时间",
},
{
type: 'title',
component: markRaw(FitsFormTitle),
field: "divider",
value: '复选框控件',
style: "background:#F2F2F2;color:#303133;line-height:32px;padding-left:16px;"
},
{
type: "checkbox",
title: "多选",
field: "checkbox1",
options: [
{
value: "104",
label: "生态蔬菜",
disabled: false
},
{
value: "105",
label: "新鲜水果",
disabled: true
},
{
value: "106",
label: "蛋糕甜点",
disabled: false
},
]
},
{
type: "checkboxAll",
component: markRaw(FitsCheckboxAll),
title: "全选组件",
field: "checkbox2",
props: {
options: new FitsCheckboxAllModel({
option: [
{
label: "生态蔬菜1",
},
{
label: "新鲜水果1",
},
{
label: "蛋糕甜点1",
}
],
})
},
},
],
option: {
form: {
labelPosition: 'right',
labelWidth: '120px',
},
onSubmit: (formData: any) => {
alert(JSON.stringify(formData))
},
},
})
)
</script>
<style lang="scss">
</style>
<style lang="scss" scoped>
</style>```
# 行内表单
行内表单展示。通过设置 option.form.inline=true
开启行内表单,并通过传入 col
设置显示多少列。
<template>
<fits-form-create :form="inlineForm" />
</template>
<script setup lang="ts">
import { FitsFormCreate } from '@/fits-components';
import { FitsFormCreateModel } from '@/fits-components/type'
const inlineForm = reactive(
new FitsFormCreateModel({
rule: [
{
type: "input",
title: "输入框",
field: "input",
},
{
type: "select",
title: "下拉选择",
field: "select",
options: [
{
value: "104",
label: "生态蔬菜",
},
{
value: "105",
label: "新鲜水果",
},
{
value: "106",
label: "蛋糕甜点",
},
]
},
{
type: "DatePicker",
title: "日期选择",
field: "DatePicker1",
},
{
type: "input",
title: "多行文本",
field: "textarea",
props: {
type: "textarea",
placeholder: "请输入商品名称",
rows: 5,
autosize: { minRows: 2, maxRows: 5 }
}
},
],
option: {
form: {
labelPosition: "right",
inline: true
},
onSubmit: (formData: any) => {
alert(JSON.stringify(formData))
},
},
col: 2,
})
)
</script>
<style lang="scss">
</style>
<style lang="scss" scoped>
</style>```
# 表单必填校验
设置必填有2种方式:
第1种,给表单项传入 effect.required=true
,使用的是默认的错误提示信息,如“xxx不能为空”。如果想自定义错误信息,需要传入一个字符串而不是 true
。
第2种,给表单项传入 validate
属性,其中包含{ required: true, message: '错误提示信息', trigger: 'change' }
对象即可。
<template>
<fits-form-create :form="simpleForm" />
</template>
<script setup lang="ts">
import { FitsFormCreate } from '@/fits-components';
import { FitsFormCreateModel } from '@/fits-components/type'
const simpleForm = reactive(
new FitsFormCreateModel({
rule: [
{
type: "input",
title: "姓名",
field: "input",
effect: {
required: true
}
},
{
type: "select",
title: "性别",
field: "select",
options: [
{
value: "0",
label: "男",
},
{
value: "1",
label: "女",
},
],
effect: {
required: true
}
},
{
type: "radio",
title: "出行方式",
field: "travelMode",
options: [
{
value: "104",
label: "步行",
},
{
value: "105",
label: "地铁",
},
],
validate: [{ required: true, message: '请选择你的出行方式', trigger: 'change' }]
},
{
type: "DatePicker",
title: "出生日期",
field: "birthday",
validate: [{ required: true, message: '请选择出生日期', trigger: 'change' }]
},
],
option: {
form: {
labelPosition: 'right',
},
onSubmit: (formData: any) => {
alert(JSON.stringify(formData))
}
},
})
)
</script>
<style lang="scss">
</style>
<style lang="scss" scoped>
</style>```
# 自定义校验规则
本例通过设置表单项的 validate
属性,展示了如何使用自定义验证规则来完成密码的二次验证。
<template>
<fits-form-create :form="simpleForm" ref="FormRef" />
</template>
<script setup lang="ts">
import { FitsFormCreate } from '@/fits-components';
import { FitsFormCreateModel } from '@/fits-components/type'
import { isPassword } from '@/utils/is';
const FormRef: any = ref(null)
const simpleForm = reactive(
new FitsFormCreateModel({
rule: [
{
type: "input",
field: "oldPwd",
title: "原密码",
props: {
placeholder: "请输入原密码",
type: "password",
showPassword: true
},
validate: [
{ required: true, type: 'string', message: "请输入原密码" },
],
},
{
type: "input",
field: "newPwd",
title: "新密码",
props: {
placeholder: "请输入新密码",
type: "password",
maxlength: 20,
showPassword: true
},
validate: [
{ required: true, type: 'string', message: "请输入新密码" },
{
validator: (rule: any, val: any, d: any) => {
return isPassword(val)
},
message: "新密码长度10位以上,包含数字、字母、符号"
}
],
},
{
type: "input",
field: "againPwd",
title: "确认密码",
props: {
placeholder: "再次确认新密码",
type: "password",
showPassword: true
},
validate: [
{ required: true, type: 'string', message: "请再次输入新密码" },
{
validator: (rule: any, val: any, d: any) => {
return val === FormRef.value.fApi.getValue('newPwd')
},
message: "密码不一致"
}
]
}
],
option: {
form: {
labelPosition: 'right',
},
onSubmit: (formData: any) => {
alert(JSON.stringify(formData))
}
},
})
)
</script>
<style lang="scss">
</style>
<style lang="scss" scoped>
</style>```
# 动态增删表单项
动态表单展示。通过获取表单组件实例,获得暴露出来的接口方法,调用相关的方法实现动态删减表单项。关于api方法调用请参照 form-create全局api。
<template>
<el-button-group style="margin:20px 30px">
<el-button @click="prependRule">
在头部追加规则
</el-button>
<el-button @click="appendRule">
在尾部追加规则
</el-button>
<el-button @click="spliceRule">
删除第一条规则
</el-button>
<el-button @click="spliceSpecifyRule">
删除指定规则
</el-button>
</el-button-group>
<fits-form-create :form="dynamicForm" ref="dynamicRef" />
<fits-form-dialog :option="spliceOpt" @submit="submitSpliceForm" @cancel="spliceOpt.visible = false" />
</template>
<script setup lang="ts">
import { FitsFormCreate, FitsFormDialog } from '@/fits-components';
import { FitsFormCreateModel } from '@/fits-components/type'
import { ElMessage } from 'element-plus';
let num = 0
const dynamicForm = reactive(
new FitsFormCreateModel({
rule: [
{
type: "input",
field: "UserName",
title: "用户名称",
props: {
placeholder: "请输入用户名称",
},
validate: [
{ required: true, message: "请输入用户名称" }
],
},
{
type: "input",
title: "文本",
field: "input2",
props: {
placeholder: "请输入商品名称",
}
},
],
option: {
form: {
labelPosition: 'right',
inline: true
},
},
col: 2
})
)
const spliceOpt = reactive({
visible: false,
forms: [
{
form: new FitsFormCreateModel({
rule: [
{
type: "input",
field: "fieldName",
title: "规则字段",
props: {
placeholder: "请输入规则字段",
},
validate: [
{ required: true, message: "请输入规则字段" }
],
}
],
option: {
form: {
labelPosition: 'right'
},
submitBtn: false,
resetBtn: false
},
})
},
],
dialogProp: {
title: '删除字段',
width: '30%'
}
})
const dynamicRef = ref()
/**
规则生成的规则
*/
function getRule() {
num++
return {
type: "input",
title: "追加规则" + num,
field: "appendInput" + num,
value: "追加规则" + num,
}
}
function prependRule() {
dynamicRef.value.fApi.prepend(getRule())
}
function appendRule() {
dynamicRef.value.fApi.append(getRule())
}
function spliceRule() {
dynamicRef.value.fApi.rule.splice(0, 1)
}
function spliceSpecifyRule() {
spliceOpt.visible = true
}
function submitSpliceForm(formValue: any) {
if (formValue.fieldName) {
console.log(dynamicRef.value.fApi.removeField(formValue.fieldName));
if (dynamicRef.value.fApi.removeField(formValue.fieldName) === undefined) {
ElMessage.error('找不到该规则')
} else {
dynamicRef.value.fApi.removeField(formValue.fieldName)
ElMessage.success('删除成功')
spliceOpt.visible = false
}
}
}
</script>
<style lang="scss">
</style>
<style lang="scss" scoped>
</style>```
# 自定义组件
自定义表单组件展示。自定义的组件需要进行全局注册,注册后可以通过 type
传入注册时的组件名,调用该组件。
<template>
<fits-form-create :form="customForm" />
</template>
<script setup lang="ts">
import { FitsFormCreate } from '@/fits-components';
import { FitsFormCreateModel, FitsCheckboxAllModel, FitsIconSelectModel, FitsTreeSelectModel } from '@/fits-components/type';
import FitsCheckboxAll from '@/fits-components/Form/Checkbox/FitsCheckboxAll.vue';
import FitsIconSelect from '@/fits-components/Form/Select/FitsIconSelect.vue';
import FitsTreeSelect from '@/fits-components/Form/Select/FitsTreeSelect.vue';
const data = [
{
id: '1',
label: 'Level 1',
children: [
{
id: '4',
label: 'Level 1-1',
},
],
},
{
id: '21',
label: 'Level 2',
children: [
{
id: '5',
label: 'Level 2-1',
},
],
},
{
id: '3',
label: 'Level 3',
},
]
const customForm = reactive(
new FitsFormCreateModel({
rule: [
{
type: 'title',
component: markRaw(FitsTreeSelect),
field: "treeSearch",
title: "下拉选择树(单选)",
props: {
options: new FitsTreeSelectModel({
select: {
placeholder: "请选择组织机构",
clearable: true
},
input: {
placeholder: "部门搜索",
},
tree: {
nodeKey: "id",
defaultExpandAll: false,
data
}
})
},
effect: {
required: true
}
},
{
field: "treeSearchMultiple",
title: "下拉选择树(多选)",
type: 'title',
component: markRaw(FitsTreeSelect),
props: {
options: new FitsTreeSelectModel({
select: {
placeholder: "请选择组织机构",
multiple: true,
clearable: true,
},
input: {
placeholder: "部门搜索",
},
tree: {
showCheckbox: true,
nodeKey: "id",
defaultExpandAll: false,
data
}
})
},
effect: {
required: true
}
},
{
field: "iconSelect",
title: "图标选择(单选)",
type: 'title',
component: markRaw(FitsIconSelect),
// value: 'edit',
props: {
options: new FitsIconSelectModel({
select: {
placeholder: "请选择图标",
clearable: true
},
input: {
placeholder: "图标搜索",
},
})
},
validate: [
{ required: true, message: "请选择图标", trigger: 'change' }
],
},
{
field: "iconSelectMultiple",
title: "图标选择(多选)",
type: 'title',
component: markRaw(FitsIconSelect),
value: ['edit', 'client'],
props: {
options: new FitsIconSelectModel({
select: {
placeholder: "请选择图标",
multiple: true,
clearable: true
},
input: {
placeholder: "图标搜索",
},
})
},
validate: [
{ type: 'array', required: true, message: "请选择图标", trigger: 'change' }
],
},
{
type: 'title',
component: markRaw(FitsCheckboxAll),
title: "多选(全选)",
field: "checkbox2",
// value: ['生态蔬菜'],
props: {
options: new FitsCheckboxAllModel({
option: [
{
label: "生态蔬菜",
},
{
label: "新鲜水果",
},
{
label: "蛋糕甜点",
}
],
})
},
effect: {
required: true
}
},
],
option: {
onSubmit: (formData: any) => {
alert(JSON.stringify(formData))
}
}
})
)
</script>
<style lang="scss">
</style>
<style lang="scss" scoped>
</style>```
# 使用组件的插槽
给表单项传入 children
数组,该数组为对象或者字符串组成。如果使用组件的默认插槽,则不需要指定slot属性。如果使用组件的指定插槽,则需要通过 slot
指明插槽名称。
<template>
<fits-form-create :form="slotForm" />
</template>
<script setup lang="ts">
import { FitsFormCreate } from '@/fits-components';
import { FitsFormCreateModel } from '@/fits-components/type'
import { Search } from '@element-plus/icons-vue'
const slotForm = reactive(
new FitsFormCreateModel({
rule: [
{
type: 'button',
field: 'slotButton',
title: '使用按钮的插槽',
props: {
type: 'primary'
},
children: [
{
type: 'div',
slot: 'icon',
component: markRaw(Search),
},
'按钮名称'
]
},
{
type: 'input',
field: 'slotInput',
title: '使用输入框的插槽',
children: [
{
type: 'div',
component: markRaw(Search),
class: 'el-icon',
slot: 'prefix',
},
{
type: 'span',
slot: 'suffix',
// 显示为文本
children: ['suffix']
},
]
},
{
type: 'select',
field: 'slotSelect',
title: '使用下拉框的插槽',
options: [
{
value: "104",
label: "生态蔬菜",
},
{
value: "105",
label: "新鲜水果",
},
],
// select的插槽
children: [
{
type: 'span',
children: ['我是select的默认插槽']
},
// 无效,未解决
{
type: 'svg',
slot: 'empty',
component: markRaw(Search),
},
// 无效,未解决
{
type: 'svg',
slot: 'prefix',
component: markRaw(Search),
}
]
},
],
option: {
submitBtn: false,
resetBtn: false
},
})
)
</script>
<style lang="scss">
</style>
<style lang="scss" scoped>
</style>```
# FitsFormCreateModel 表单属性
属性 | 说明 | 类型 | 必填项 | 默认值 |
---|---|---|---|---|
rule | 生成表单的规则 | FitsFormCreateRuleProps | 必填 | - |
option | 表单全局配置 | FitsFormCreateOptionModel | 非必填 | - |
col | 表单展示列数 | number | 非必填 | - |
# FitsFormCreateRuleProps 表单项属性
属性 | 说明 | 类型 | 必填项 | 默认值 |
---|---|---|---|---|
field | 表单项的字段名称 | string | 必填 | - |
type | 表单项类型 | string | 必填 | - |
component | 自定义组件 | Component | 非必填 | - |
title | 表单项的标签文本 | string | 非必填 | - |
value | 表单项的字段值 | string / number / Array / Object | 非必填 | - |
props | 组件的属性配置 | Object | 非必填 | - |
validate | 表单项的验证规则 | Array | 非必填 | - |
表单项的验证规则:form-create验证规则说明open in new window
更多表单项属性:form-create表单项属性open in new window
# FitsFormCreateOptionModel 表单全局配置属性
属性 | 说明 | 类型 | 回调参数 | 默认值 |
---|---|---|---|---|
form | 表单显示规则配置 | formopen in new window | - | { labelPosition: 'top', labelWidth: '80px', size: 'default'} |
row | 表单布局配置 | rowopen in new window | - | { gutter: 0, type: 'flex', align: 'middle', justify: 'start', tag: 'div' } |
submitBtn | 提交按钮的配置 | boolean / FitsFormCreateBtnType | - | { show: true, size: "default", innerText: "保存", color: "#007dff" } |
resetBtn | 重置按钮的配置 | boolean / FitsFormCreateBtnType | - | { show: true, size: "default", innerText: "取消" } |
onSubmit | 表单提交后的回调函数 | Function(formData,fApi) | - | - |
onReload | 表单重载后的回调函数 | Function(fApi) | - | - |
mounted | 表单创建成功后回调函数 | Function(fApi) | - | - |
global | 设置所有表单项的通用配置 | Object | - | - |
# FitsFormCreateBtnType属性
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
show | 是否显示按钮 | boolean | - |
innerText | 按钮的文字 | string | - |
click | 按钮的点击事件 | Function(fapi) | - |
更多属性请参考 el-buttonopen in new window