Form 表单
表单组 ElPlusFormGroup
开发过程中,会遇到一个表单被分为很多块的情况,此时就需要用到表单组。表单组的配置大致与 formConfig 一致。
代码
vue
<ElPlusFormGroup v-model="formGroupData" :formGroup="formGroupConfig" />
<script lang="ts" setup>
import { ref, reactive } from 'vue'
let formGroupData = reactive({} as any)
const formGroupConfig = ref({
column: 2,
beforeRequest: (formData: any) => {
console.log('当前表单数据为:', formData)
if (formData.online.indexOf(3) < 0) {
ElMessage.warning('上架平台必须包含 拼多多,请重新选择!')
return false
}
// 设置其他属性
formData.xxx = 'xxx'
return formData
},
requestFn: (postData: any) => {
return new Promise((resolve) => {
// 模拟数据异步提交
setTimeout(() => {
console.log('数据已成功保存: ', postData)
resolve({ code: 200, msg: 'success' })
}, 1000)
})
},
success: ({ response, callBack }: IFormBack) => {
console.log('请求结果: ', response)
ElMessage.success('保存成功~')
callBack()
},
group: [
{
title: '基本信息',
column: 2,
formDesc: {
name: { type: 'input', label: '商品名称', maxlength: 30, required: true, colspan: 2 },
price: { type: 'number', label: '商品价格', required: true, precision: 2, tip: '元' },
type: { type: 'cascader', label: '商品类型', options: 'goodsTypeList', required: true },
expiration: { type: 'select', label: '保质期', required: true, options: 'expirationOptions' }
} as IFormDesc
},
{
title: '价格库存信息',
column: 2,
formDesc: {
stock: { type: 'number', label: '商品库存', required: true, tip: '件' },
storeTime: { type: 'date', label: '入库时间', required: true },
taxRate: { type: 'select', label: '税率', default: 0.05, required: true, options: 'taxRateOptions' }
} as IFormDesc
},
{
title: '活动信息',
column: 2,
formDesc: {
online: { type: 'checkbox', label: '上架平台', required: true, options: 'onLineOptions', colspan: 4 },
sellType: { type: 'radio', label: '折扣类型', required: true, options: 'sellTypeOptions', colspan: 2 },
activeTime: { type: 'daterange', label: '活动时间', required: true }
} as IFormDesc
},
{
title: '商品图文信息',
column: 2,
formDesc: {
imageList: { type: 'upload', label: '商品图片', limit: 9, required: true, multiple: true, colspan: 2 },
fileList: { type: 'upload', upType: 'file', label: '商品附件', multiple: true, colspan: 2, required: true }
} as IFormDesc
},
{
title: '其他信息',
column: 2,
formDesc: {
enabled: { type: 'switch', label: '启用状态', default: 1, required: true },
remark: { type: 'textarea', label: '备注', colspan: 2 }
} as IFormDesc
}
]
} as IFormGroupConfig)
</script>
<ElPlusFormGroup v-model="formGroupData" :formGroup="formGroupConfig" />
<script lang="ts" setup>
import { ref, reactive } from 'vue'
let formGroupData = reactive({} as any)
const formGroupConfig = ref({
column: 2,
beforeRequest: (formData: any) => {
console.log('当前表单数据为:', formData)
if (formData.online.indexOf(3) < 0) {
ElMessage.warning('上架平台必须包含 拼多多,请重新选择!')
return false
}
// 设置其他属性
formData.xxx = 'xxx'
return formData
},
requestFn: (postData: any) => {
return new Promise((resolve) => {
// 模拟数据异步提交
setTimeout(() => {
console.log('数据已成功保存: ', postData)
resolve({ code: 200, msg: 'success' })
}, 1000)
})
},
success: ({ response, callBack }: IFormBack) => {
console.log('请求结果: ', response)
ElMessage.success('保存成功~')
callBack()
},
group: [
{
title: '基本信息',
column: 2,
formDesc: {
name: { type: 'input', label: '商品名称', maxlength: 30, required: true, colspan: 2 },
price: { type: 'number', label: '商品价格', required: true, precision: 2, tip: '元' },
type: { type: 'cascader', label: '商品类型', options: 'goodsTypeList', required: true },
expiration: { type: 'select', label: '保质期', required: true, options: 'expirationOptions' }
} as IFormDesc
},
{
title: '价格库存信息',
column: 2,
formDesc: {
stock: { type: 'number', label: '商品库存', required: true, tip: '件' },
storeTime: { type: 'date', label: '入库时间', required: true },
taxRate: { type: 'select', label: '税率', default: 0.05, required: true, options: 'taxRateOptions' }
} as IFormDesc
},
{
title: '活动信息',
column: 2,
formDesc: {
online: { type: 'checkbox', label: '上架平台', required: true, options: 'onLineOptions', colspan: 4 },
sellType: { type: 'radio', label: '折扣类型', required: true, options: 'sellTypeOptions', colspan: 2 },
activeTime: { type: 'daterange', label: '活动时间', required: true }
} as IFormDesc
},
{
title: '商品图文信息',
column: 2,
formDesc: {
imageList: { type: 'upload', label: '商品图片', limit: 9, required: true, multiple: true, colspan: 2 },
fileList: { type: 'upload', upType: 'file', label: '商品附件', multiple: true, colspan: 2, required: true }
} as IFormDesc
},
{
title: '其他信息',
column: 2,
formDesc: {
enabled: { type: 'switch', label: '启用状态', default: 1, required: true },
remark: { type: 'textarea', label: '备注', colspan: 2 }
} as IFormDesc
}
]
} as IFormGroupConfig)
</script>
动态组 & 插槽
单个 group 对象也支持动态 vif: boolean | () => boolean 。如果仅仅表单不满足你的需求时,可以使用插槽进行扩展。目前可使用的插槽分别为 titleX / topX 和 defaultX (其中 X 表示表单组所在的下标,以 0 开始)。注:本例子使用的 ElPlusTable 组件,是 CRUD 中另一个核心组件。
代码
html
<ElPlusFormGroup v-model="formGroupData2" :formGroup="formGroupConfig2">
<template #top0>
<div style="border: 1px solid var(--vp-c-brand); margin-bottom: 12px; padding: 12px;">这里是第1组表单的 top 插槽</div>
</template>
<template #title1>
<div class="title-line">
这里是第2组表单的 title 插槽
<span style="color: var(--vp-c-primary)">(修改 是否入库 可动态显示和隐藏)</span>
</div>
</template>
<template #default2>
<div style="margin-bottom: 12px; border-radius: 4px; border: 1px solid var(--el-color-info-light-3); padding: 20px;">
活动列表(这里是第3组表单的 default 插槽)
<ElPlusTable v-model="tableData" :tableConfig="tableConfig" :isPager="false"></ElPlusTable>
</div>
</template>
</ElPlusFormGroup>
<script lang="ts" setup>
import { ref, reactive } from 'vue'
let formGroupData2 = reactive({} as any)
const formGroupConfig2 = ref({
column: 2,
group: [
{
title: '基本信息',
column: 2,
formDesc: {
name: { type: 'input', label: '商品名称', maxlength: 30, required: true, colspan: 2 },
isStore: { type: 'switch', label: '是否入库', default: 1, required: true }
} as IFormDesc
},
{
title: '价格库存信息',
column: 2,
vif: () => formGroupData2.isStore,
formDesc: {
stock: { type: 'number', label: '商品库存', required: true, tip: '件' },
storeTime: { type: 'date', label: '入库时间', required: true },
taxRate: { type: 'select', label: '税率', default: 0.05, required: true, options: 'taxRateOptions' }
} as IFormDesc
},
{
title: '活动信息',
column: 2,
formDesc: {
online: { type: 'checkbox', label: '上架平台', required: true, options: 'onLineOptions', colspan: 4 },
sellType: { type: 'radio', label: '折扣类型', required: true, options: 'sellTypeOptions', colspan: 2 },
activeTime: { type: 'daterange', label: '活动时间', required: true }
} as IFormDesc
},
{
title: '其他信息',
column: 2,
formDesc: {
enabled: { type: 'switch', label: '启用状态', default: 1, required: true },
remark: { type: 'textarea', label: '备注', colspan: 2 }
} as IFormDesc
}
]
} as IFormGroupConfig)
let tableData = reactive([
{ name: '国庆中秋大促', startTime: '2023-09-25', endTime: '2023-10-10', createBy: 'admin', createTime: '2023-09-20' },
{ name: '双11抢购', startTime: '2023-11-01', endTime: '2023-11-30', createBy: 'admin', createTime: '2023-10-20' }
] as any[])
const tableConfig = ref({
column: [
{ prop: 'name', label: '活动名称' },
{ prop: 'startTime', label: '开始时间' },
{ prop: 'endTime', label: '结束时间' },
{ prop: 'createBy', label: '创建人' },
{ prop: 'createTime', label: '创建时间' }
]
} as ITableConfig)
</script>
<ElPlusFormGroup v-model="formGroupData2" :formGroup="formGroupConfig2">
<template #top0>
<div style="border: 1px solid var(--vp-c-brand); margin-bottom: 12px; padding: 12px;">这里是第1组表单的 top 插槽</div>
</template>
<template #title1>
<div class="title-line">
这里是第2组表单的 title 插槽
<span style="color: var(--vp-c-primary)">(修改 是否入库 可动态显示和隐藏)</span>
</div>
</template>
<template #default2>
<div style="margin-bottom: 12px; border-radius: 4px; border: 1px solid var(--el-color-info-light-3); padding: 20px;">
活动列表(这里是第3组表单的 default 插槽)
<ElPlusTable v-model="tableData" :tableConfig="tableConfig" :isPager="false"></ElPlusTable>
</div>
</template>
</ElPlusFormGroup>
<script lang="ts" setup>
import { ref, reactive } from 'vue'
let formGroupData2 = reactive({} as any)
const formGroupConfig2 = ref({
column: 2,
group: [
{
title: '基本信息',
column: 2,
formDesc: {
name: { type: 'input', label: '商品名称', maxlength: 30, required: true, colspan: 2 },
isStore: { type: 'switch', label: '是否入库', default: 1, required: true }
} as IFormDesc
},
{
title: '价格库存信息',
column: 2,
vif: () => formGroupData2.isStore,
formDesc: {
stock: { type: 'number', label: '商品库存', required: true, tip: '件' },
storeTime: { type: 'date', label: '入库时间', required: true },
taxRate: { type: 'select', label: '税率', default: 0.05, required: true, options: 'taxRateOptions' }
} as IFormDesc
},
{
title: '活动信息',
column: 2,
formDesc: {
online: { type: 'checkbox', label: '上架平台', required: true, options: 'onLineOptions', colspan: 4 },
sellType: { type: 'radio', label: '折扣类型', required: true, options: 'sellTypeOptions', colspan: 2 },
activeTime: { type: 'daterange', label: '活动时间', required: true }
} as IFormDesc
},
{
title: '其他信息',
column: 2,
formDesc: {
enabled: { type: 'switch', label: '启用状态', default: 1, required: true },
remark: { type: 'textarea', label: '备注', colspan: 2 }
} as IFormDesc
}
]
} as IFormGroupConfig)
let tableData = reactive([
{ name: '国庆中秋大促', startTime: '2023-09-25', endTime: '2023-10-10', createBy: 'admin', createTime: '2023-09-20' },
{ name: '双11抢购', startTime: '2023-11-01', endTime: '2023-11-30', createBy: 'admin', createTime: '2023-10-20' }
] as any[])
const tableConfig = ref({
column: [
{ prop: 'name', label: '活动名称' },
{ prop: 'startTime', label: '开始时间' },
{ prop: 'endTime', label: '结束时间' },
{ prop: 'createBy', label: '创建人' },
{ prop: 'createTime', label: '创建时间' }
]
} as ITableConfig)
</script>